写点什么

Spring Cloud Gateway 限流实战,万字详解微服务的哨兵机制

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

    阅读完需:约 7 分钟

@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 {


@Be


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


an


KeyResolver userKeyResolver() {


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


}


}


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


package com.bolingcavalry.gateway;


import org.springframework.boot.SpringApplication;


import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication


public class RequestRateLimiterApplication {


public static void main(String[] args) {


SpringApplication.run(RequestRateLimiterApplication.class,args);


}


}


  • 代码写完了,接下来开始验证;

验证(桶容量等于入桶速度)

  • 首先验证的是桶容量等于入桶速度时的效果,请修改 gateway-requestratelimiter 应用的 application.yml 中文件,使得 redis-rate-limiter.replenishRate 和 redis-rate-limiter.burstCapacity 的值都等于 100,也就是说桶的大小等于 100,每秒放入的令牌数也是 100

  • 确保 redis 已经启动,并且与 application.yml 中的配置保持一直

  • 启动 nacos(provider-hello 依赖)

  • 启动服务提供者 provider-hello

  • 启动 gateway-requestratelimiter

  • 为了模拟 web 请求,我这里使用了 Apache Benchmark,windows 版本的下载地址:


https://www.apachelounge.com/download/VS16/binaries/httpd-2.4.48-win64-VS16.zip


  • 上述文件下载解压后即可使用,在控制台进入 Apache24\bin 后执行以下命令,意思是向指定地址发送 10000 个请求,并发数为 2:


ab -n 10000 -c 2 http://localhost:8081/hello/userinfo?username=Tom


  • 控制台输出如下,可见不到八秒的时间,只成功了 800 个,证明限流符合预期:


验证(桶容量大于入桶速度)

  • 接下来试试桶容量大于入桶速度时的限流效果,这对于我们控制峰值响应有很重要的参考价值

  • 请修改 gateway-requestratelimiter 应用的 application.yml 中文件,redis-rate-limiter.replenishRate 维持 100 不变,但是 redis-rate-limiter.burstCapacity 改成 200,也就是说每秒放入的令牌数还是 100,但桶的容量翻倍了

  • 重启应用 gateway-requestratelimiter

用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
Spring Cloud Gateway限流实战,万字详解微服务的哨兵机制