大龄后端转后厨...|

Vermeer

园龄:3年7个月粉丝:6关注:0

2021-08-17 00:06阅读: 1999评论: 0推荐: 0

Gateway 网关 之 限流

可以利用Gateway中RequestRateLimiter实现限流

常见的限流算法

1、计数器算法

以QPS(每秒查询率Queries-per-second)为100举例。

从第一个请求开始计时。每个请求让计数器加一。当到达100以后,其他的请求都拒绝。

如果1秒钟内前200ms请求数量已经到达了100,后面800ms中500次请求都被拒绝了,这种情况称为“突刺现象”

 

2、漏桶算法

和生活中漏桶一样,有一个水桶,下面有一个”漏眼”往出漏水,不管桶里有多少水,漏水的速率都是一样的。但是既然是一个桶,桶里装的水都是有上限的。当到达了上限新进来的水就装不了(主要出现在突然倒进来大量水的情况)。漏桶算法可以解决突刺现象。

 

3、令牌桶算法

令牌桶算法可以说是对漏桶算法的一种改进。

在桶中放令牌,请求获取令牌后才能继续执行。如果桶中没有令牌,请求可以选择进行等待或者直接拒绝。

由于桶中令牌是按照一定速率放置的,所以可以一定程度解决突发访问。如果桶中令牌最多有100个,qps最大为100

 

 

 


案例:

Gateway中限流,RequestRateLimiter是基于Redis和Lua脚本实现的令牌桶算法

配置:

配置文件属性参考:RequestRateLimiterGatewayFilterFactory及内部类 Config,RateLimiter,KeyResolver 的字段

 

复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: member-demo
          uri: lb://my-member
          predcates:
            - name: Path
              args:
                - patterns=/member/**,/my-member/**
          
          filters:  
            # 配置令牌桶
            - name: RequestRateLimiter
              args:
                # 配置类:RateLimiter 实现类 RedisRateLimiter 对象
                redis-rate-limiter:
                  defaultRateLimiter:
                    defaultConfig:
                      # 每秒生成令牌个数
                      replenishRate: 1
                      # 令牌桶上线容量
                      burstCapacity: 5
 
                    # 自定义一个 keyResolver 实现 KeyResolver MyKeyResolver,注入容器,使用Spring的EL表达式读取值
                    defaultKeyResolver: '#{@myKeyResolver}'
 
  # 令牌桶使用到 Redis ,需要配置Redis连接属性
  redis:
    host: behelpful-redis
    port: 6379
    password: behelpful@8888
复制代码

 


自定义令牌桶规则:

just() 方法参数表示根据什么进行限流。实例中是根据主机名进行限流。参数值影响Redis

复制代码
@Component
public class MyKeyResolver implements KeyResolver {
   /**
    * <String> 字符串泛型,代表令牌分给谁,可以是IP地址也可以是数字字符串,如果返回 "1",表示所有客户端一表只有一个令牌
    *
    * @param exchange
    * @return
    */
   @Override
   public Mono<String> resolve(ServerWebExchange exchange) {
      ServerHttpRequest request = exchange.getRequest();
      String remoteAddr = request.getRemoteAddress().getAddress().getHostAddress();
      // 对每个客户端IP进行限流
      return Mono.just(remoteAddr);
   }
}
复制代码

 

>>>>>>>>>>>>> 下一篇: https://www.cnblogs.com/chxlay/p/15150554.html   <<<<<<<<<<<<<<<<<<<<<<

 
posted @   Vermeer  阅读(1999)  评论(0编辑  收藏  举报

喜欢请打赏

扫描二维码打赏

了解更多

点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起