Spring Cloud Gateway限流实战

2023-02-19 0 448

热烈欢迎出访我的GitHub

第一集概要

责任编辑是《Spring Cloud Gateway两栖作战》系列产品的第八篇,历经后面的自学,咱对冷却系统已介绍得相差无几,那时来Bazelle冷却系统的最终两个新浪网:开闭(RequestRateLimiter )

预设的开闭器是如前所述redis同时实现的,开闭演算法是我们熟识的副本桶(Token Bucket Algorithm),有关副本捅的基本上原理就无此此进行了,精明的您看一看右图如果就懂了:装令牌的桶耗电量非常有限,比如最多20个,副本步入桶的速率静止(特别注意,这儿是和漏桶演算法的差别),比如每秒钟10个,顶部每一允诺能领到副本才会被处置:

Spring Cloud Gateway限流实战

RequestRateLimiter基本上拳法

采用RequestRateLimiter冷却系统的关键步骤比较单纯:

预备需用的redis

maven或是gradle中加进倚赖org.springframework.boot:spring-boot-starter-data-redis-reactive

确认依照甚么层次开闭,比如依照允诺中的username模块开闭,这是透过撰写KeyResolverUSB的同时实现来顺利完成的

配置application.yml文件,加进冷却系统

以内是采用RequestRateLimiter冷却系统的拳法了,单纯么?接下去,咱先代码再校正

源代码浏览

Spring Cloud Gateway限流实战

这个git项目中有数个文件夹,第一集的源代码在spring-cloud-tutorials文件夹下,如右图红框所示:

Spring Cloud Gateway限流实战

spring-cloud-tutorials文件夹下有数个子工程,第一集的代码是gateway-requestratelimiter,如右图红框所示:

Spring Cloud Gateway限流实战

预备工作

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

@GetMapping(“/userinfo”)

public String userInfo(@RequestParam(“username”) String username) {

return Constants.HELLO_PREFIX + ” ” + username + “, ” + dateStr();

后面的测试咱就用上述USB;

代码

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

spring-cloud-tutorials

com.bolingcavalry

1.0-SNAPSHOT

4.0.0

gateway-requestratelimiter

com.bolingcavalry

common

${project.version}

org.springframework.cloud

spring-cloud-starter-gateway

org.springframework.boot

spring-boot-starter-data-redis-reactive

命令行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

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

配置文件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

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;

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版本的浏览地址:

上述文件浏览解压后即可采用,在控制台步入Apache24\bin后执行以下命令,意思是向指定地址发送10000个允诺,并发数为2:

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

Spring Cloud Gateway限流实战

校正(桶耗电量大于入桶速率)

接下去试试桶耗电量大于入桶速率时的开闭效果,这对于我们控制峰值响应有很重要的参考价值

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

重启应用gateway-requestratelimiter

再次执行以下命令,意思是向指定地址发送10000个允诺,并发数为2:

测试结果如右图,可见符合预期,可以将桶内副本全部用掉,以支撑峰值超过QPS的场景:

Spring Cloud Gateway限流实战

校正(根据username的层次开闭)

接下去校正开闭的层次,究竟是不是依照允诺模块username的值来开闭的

咱打开两个命令行,同时发送请求(动作要快),第两个的username等于Tom,第二个等于Jerry,理论上推测,如果都是8秒内顺利完成,那么每一命令都有900个允诺能成功

测试结果如右图,可见符合预期,每一username用的是自己的副本:

Spring Cloud Gateway限流实战

至此,Spring Cloud Gateway开闭两栖作战已经顺利完成,如此单纯易用的开闭方案,希望能给您的自学和采用带来参考

热烈欢迎关注娱乐号:程序员欣宸

自学路上,你不孤单,欣宸原创一路相伴…

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务