随笔- 136  文章- 0  评论- 8  阅读- 26万 

  gateway默认给我们提供了限流实现,也就是网关拦截器RequestRateLimiter。

 

6.1 令牌桶限流算法 RequestRateLimiter底层实现是令牌桶算法;

  令牌桶内存储令牌,令牌桶需要设置令牌容量,也就是系统最大的并发大; 以一定的速率生成令牌(具体速率根据系统性能设置),放到令牌桶,如果桶慢了,则丢弃; 客户端来一个请求,则先去令牌桶获取令牌,拿到令牌,则处理请求,否则 丢弃或者返回失败;

 令牌桶算法的优点:
  (1)通过恒定的速率生成令牌桶,能够让请求处理更均匀,不会出现短时间大量的请求处理;
  (2)比较友好的控制高并发;  
page16image24291456

page17image9779312

6.2 Gateway网关限流实例
  Spring Cloud Gateway官方提供了 RequestRateLimiterGatewayFilterFactory 过滤器工厂,使用Redis 和 Lua 脚本实现了令牌桶,来实现网关限流; 添加下Redis依赖:

1
2
3
4
5
6
7
8
<!-- spring boot redis 缓存引入 --> <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- lettuce pool 缓存连接池 --> <dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

 

6.2.1 URI限流 

配置类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.java1234.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;
/**
* 限流规则配置类
* @author java1234
*/
@Configuration
public class KeyResolverConfiguration {
    @Bean
    public KeyResolver pathKeyResolver(){
        /*return new KeyResolver() {
            @Override
            public Mono<String> resolve(ServerWebExchange exchange) {
                return Mono.just(exchange.getRequest().getURI().getPath());
} };*/
return exchange -> Mono.just(exchange.getRequest().getURI().getPath()); // URI限流
} }

 

yml配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      routes:
        - id: rateLimiter
          uri: http://localhost:8080/
          predicates:
           - Path=/product/**
          filters:
           - name: RequestRateLimiter # 限流过滤器
             args:           
                    redis-rate-limiter.replenishRate: 1 # 令牌桶每秒填充速率 r
            redis-rate-limiter.burstCapacity: 2 # 令牌桶总容量 <br>            redis-rate-limiter.requestedTokens: 1 # 一个请求需要消费的令牌数 <br>            key-resolver: "#{@pathKeyResolver}"
  redis: # redis配置
    host: 192.168.0.103 # IP
    port: 6379 # 端口
    password: # 密码
    connect-timeout: 10s # 连接超时时间 <br>    lettuce: # lettuce redis客户端配置
      pool: # 连接池配置
        max-active: 8 # 连接池最大连接数(使用负值表示没有限制) 默认 8 <br>        max-wait: 200s # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1 <br>        max-idle: 8 # 连接池中的最大空闲连接 默认 8
        min-idle: 0 # 连接池中的最小空闲连接 默认 0  

 

访问过多之后,报429错误;

page19image27011232page19image27014768

 

6.2.2 参数限流 配置类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.java1234.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;
/**
* 限流规则配置类
* @author java1234
*/
@Configuration
public class KeyResolverConfiguration {
    @Bean
    public KeyResolver parameterKeyResolver(){
        /*return new KeyResolver() {
            @Override
            public Mono<String> resolve(ServerWebExchange exchange) {
                return
Mono.just(exchange.getRequest().getQueryParams().getFirst("token"));
            }
};*/
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("token")); // 参数限流
} }

 

请求带一个参数:http://localhost/product/32?token=fdafa

page20image24445120 page20image27007904

6.2.3 IP限流 配置类:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.java1234.config;<br><br>import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* 限流规则配置类
* @author java1234
*/
@Configuration
public class KeyResolverConfiguration {
    @Bean
    public KeyResolver ipKeyResolver(){
        /*return new KeyResolver() {
            @Override
            public Mono<String> resolve(ServerWebExchange exchange) {
                return
Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
            }
};*/
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName()); // IP限流
} }

 

 posted on   wu小强  阅读(1348)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示