写点什么

Spring Cloud Gateway 限流实战

作者:Java高工P7
  • 2021 年 11 月 11 日
  • 本文字数:2195 字

    阅读完需:约 7 分钟

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

本篇概览

  • 本文是《Spring Cloud Gateway 实战》系列的第八篇,经过前面的学习,咱们对过滤器已了解得差不多,今天来补全过滤器的最后一个版块:限流(RequestRateLimiter )

  • 默认的限流器是基于 redis 实现的,限流算法是大家熟悉的令牌桶(Token Bucket Algorithm),关于令牌捅的原理就不在此展开了,聪明的您看一眼下图应该就懂了:装令牌的桶容量有限,例如最多 20 个,令牌进入桶的速度恒定(注意,这里是和漏桶算法的区别),例如每秒 10 个,底部每个请求能拿到令牌才会被处理:


RequestRateLimiter 基本套路

  • 使用 RequestRateLimiter 过滤器的步骤非常简单:


  1. 准备可用的 redis

  2. maven 或者 gradle 中添加依赖 org.springframework.boot:spring-boot-starter-data-redis-reactive

  3. 确定按照什么维度限流,例如按照请求中的 username 参数限流,这是通过编写 KeyResolver 接口的实现来完成的

  4. 配置 application.yml 文件,添加过滤器


  • 以上就是使用 RequestRateLimiter 过滤器的套路了


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


,简单么?接下来,咱们先编码再验证

源码下载

  • 本篇实战中的完整源码可在 GitHub 下载到,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos):


| 名称 | 链接 | 备注 |


| :-- | :-- | :-- |


| 项目主页 | https://github.com/zq2599/blog_demos | 该项目在 GitHub 上的主页 |


| git 仓库地址(https) | https://github.com/zq2599/blog_demos.git | 该项目源码的仓库地址,https 协议 |


| git 仓库地址(ssh) | git@github.com:zq2599/blog_demos.git | 该项目源码的仓库地址,ssh 协议 |


  • 这个 git 项目中有多个文件夹,本篇的源码在 spring-cloud-tutorials 文件夹下,如下图红框所示:



  • spring-cloud-tutorials 文件夹下有多个子工程,本篇的代码是 gateway-requestratelimiter,如下图红框所示:


准备工作

  • 为了更好的演示 Gateway 的效果,在服务提供者 provider-hello 的代码(Hello.java)中新增一个 web 接口,可以接受一个入参:


@GetMapping("/userinfo")


public String userInfo(@RequestParam("username") String username) {


return Constants.HELLO_PREFIX + " " + username + ", " + dateStr();


}


  • 后面的测试咱们就用上述接口;

编码

  • 在父工程 spring-cloud-tutorials 之下新增子工程 gateway-requestratelimiter,其 pom.xml 内容如下,重点是 org.springframework.boot:spring-boot-starter-data-redis-reactive:


<?xml version="1.0" encoding="UTF-8"?>


<project xmlns="http://maven.apache.org/POM/4.0.0"


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"


xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">


<parent>


<artifactId>spring-cloud-tutorials</artifactId>


<groupId>com.bolingcavalry</groupId>


<version>1.0-SNAPSHOT</version>


</parent>


<modelVersion>4.0.0</modelVersion>


<artifactId>gateway-requestratelimiter</artifactId>


<dependencies>


<dependency>


<groupId>com.bolingcavalry</groupId>


<artifactId>common</artifactId>


<version>${project.version}</version>


</dependency>


<dependency>


<groupId>org.springframework.cloud</groupId>


<artifactId>spring-cloud-starter-gateway</artifactId>


</dependency>


<dependency>


<groupId>org.springframework.boot</groupId>


<artifactId>spring-boot-starter-data-redis-reactive</artifactId>


</dependency>


</dependencies>


</project>


  • 配置文件 application.yml,请注意 RequestRateLimiter 的几个参数,已经用中文添加了详细的注释:


server:


#服务端口


port: 8081


spring:


application:


name: circuitbreaker-gateway

redis 配置

redis:


host: 192.168.50.43


port: 6379


cloud:


gateway:


routes:


  • id: path_route


uri: http://127.0.0.1:8082


predicates:


  • Path=/hello/**


filters:


  • name: RequestRateLimiter


args:

令牌入桶的速度为每秒 100 个,相当于 QPS

redis-rate-limiter.replenishRate: 100

桶内能装 200 个令牌,相当于峰值,要注意的是:第一秒从桶内能去 200 个,但是第二秒只能取到 100 个了,因为入桶速度是每秒 100 个

redis-rate-limiter.burstCapacity: 200

每个请求需要的令牌数

redis-rate-limiter.requestedTokens: 1


  • 指定限流维度的代码 CustomizeConfig.java,这里是根据请求参数 username 的值来限流的,假设真实请求中一半请求的 username 的等于 Tom,另一半的 username 的等于 Jerry,按照 application.yml 的配置,Tom 的请求 QPS 为 10,Jerry 的 QPS 也是 10:


package com.bolingcavalry.gateway.config;


import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;


import org.springframework.context.annotation.Bean;


import org.springframework.context.annotation.Configuration;


import reactor.core.publisher.Mono;


import java.util.Objects;


@Configuration


public class CustomizeConfig {


@Bean


KeyResolver userKeyResolver() {


return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("username"));


}


}


  • 毫无营养的启动类 RequestRateLimiterApplication.java:


package com.bolingcavalry.gateway;


import org.springframework.boot.SpringApplication;

用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
Spring Cloud Gateway限流实战