admin管理员组

文章数量:821333

SpringCloud Gateway 限速路由器的过滤器

一:限速路由器的过滤器

1.1 限速在高并发场景中比较常用的手段之一,可以有效的保障服务的整体稳定性,Spring Cloud Gateway 提供了基于 Redis 的限流方案。
所以我们首先需要添加对应的依赖包spring-boot-starter-data-redis-reactive

1.2 修改 pom.xml 文件,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".0.0" xmlns:xsi=""xsi:schemaLocation=".0.0 .0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.springcloud</groupId><artifactId>springcloud-hx</artifactId><version>1.0-SNAPSHOT</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>eureka-gateway-client</artifactId><version>0.0.1-SNAPSHOT</version><name>eureka-gateway-client</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Greenwich.RELEASE</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!--<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

增加了spring-boot-starter-data-redis-reactive的依赖

        <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId></dependency>

1.3 修改 application-predicate-mehtod.yml 文件,需要添加 Redis 地址和限流的相关配置,代码如下:

server:port: 8769#---         #三个横线表示再创建一个配置文件
spring:#profiles: predicate-method #配置文件名 和 spring.profiles.active 相对应#配置程序名为eureka-gateway-clientapplication:name: eureka-gateway-client#redis 配置  redis:host: localhostpassword: 123456port: 6379  cloud:#设置路由规则gateway:discovery:locator:#是否与服务注册于发现组件进行结合,通过 serviceId 转发到具体的服务实例。#默认为 false,设为 true 便开启通过服务中心的自动根据 serviceId 创建路由的功能enabled: true##表示将请求路径的服务名配置改成小写  因为服务注册的时候,向注册中心注册时将服务名转成大写的了lower-case-service-id: trueroutes:#我们自定义的路由 ID,保持唯一性- id: predicate_path#代表从注册中心获取服务,且以lb(load-balance)负载均衡方式转发uri: lb://eureka-client/#uri: http://localhost:8762#断言predicates:#表示GET请求,都会被路由到uri- Method=GETfilters:- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 10redis-rate-limiter.burstCapacity: 20key-resolver: '#{@ipKeyResolver}'# 配置了RequestRateLimiter的限流过滤器,该过滤器需要配置三个参数replenishRate,burstCapacity,key-resolver# redis-rate-limiter.replenishRate:允许用户每秒处理多少个请求# redis-rate-limiter.burstCapacity:令牌桶的容量,允许在一秒钟内完成的最大请求数# key-resolver:使用 SpEL 按名称引用 bean (RateLimiterConfig 类中的bean)
logging:level:org.springframework.cloud.gateway: debugeureka:client:#服务注册地址serviceUrl:#注意: Eureka Server 的注册地址#将服务提供者注册到三个Eureka Server中去#defaultZone: http://peer1:8001/eureka/,http://peer2:8002/eureka/,http://peer3:8003/eureka/#defaultZone: http://peer1:8001/eureka/defaultZone: http://localhost:8761/eureka/

增加了这部分的代码

  1. filter 名称必须是 RequestRateLimiter
  2. redis-rate-limiter.replenishRate:允许用户每秒处理多少个请求
  3. redis-rate-limiter.burstCapacity:令牌桶的容量,允许在一秒钟内完成的最大请求数
  4. key-resolver:使用 SpEL 按名称引用 bean

1.4 在eureka-gateway-client 项目中设置限流的策略,创建 RateLimiterConfig 类。

package com.example.eurekagatewayclient.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;@Configuration
public class RateLimiterConfig {/*** 根据请求参数中的 user 字段来限流** @return*//*@Beanpublic KeyResolver userKeyResolver() {return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));}*//*** 获取请求地址的uri作为限流key。* @return*//*@BeanKeyResolver apiKeyResolver() {return exchange -> Mono.just(exchange.getRequest().getPath().toString());}*//*** 根据请求 IP 地址来限流** @return*/@Beanpublic KeyResolver ipKeyResolver() {System.out.println("##############ipKeyResolver########################");return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());}
}

这样网关就可以根据不同策略来对请求进行限流了。

1.5 启动 eureka-serve, eureka-client (8762,8763 端口),eureka-gateway-client 服务,浏览器访问 http://localhost:8761/

用jmeter进行压测,配置10thread去循环请求lcoalhost:8769/HiController/aaa,循环间隔1s。从压测的结果上看到有部分请求通过,由部分请求失败。通过redis客户端去查看redis中存在的key。如下:

从结果中可以看出 filter 生效了。

本文标签: SpringCloud Gateway 限速路由器的过滤器