springCloud通过zuul-ratelimit实现zuul网关限流

springCloud配置

网关:zuul
注册中心:eureka


4种限流策略(type)

1、User:通过对已认证的用户进行限流
2、Origin:针对请求的Origin限流,ip限流
3、url:对于url进行限流
4、不配置type即默认根据servceId进行限流,即根据服务进行限流

临时变量储存方式(repository)

1、IN_MEMORY:默认存储方式,基于ConcrrentHashMap
2、REDIS:基于redis存储,zuul多节点部署的时候建议用
3、JPA:spring data JPA 基于数据库存储
4、CONSUL:consul 的kv存储
5、BUKET4J:一个Java编写的基于令牌桶算法的限流库

ratelimit参数配置事例:

zuul:
 
    ratelimit:
 
        key-prefix: your-prefix  #对应用来标识请求的key的前缀,自行设置
 
        enabled: true #是否开启限流
 
        repository: REDIS  #对应存储类型(用来存储统计信息)
 
        behind-proxy: true  #代理之后
 
        default-policy: #可选 - 针对所有的路由配置的策略,除非特别配置了policies
 
             limit: 10 #可选 - 每个刷新时间窗口对应的请求数量限制
 
             quota: 1000 #可选-  每个刷新时间窗口对应的请求时间限制(秒)
 
             refresh-interval: 60 # 刷新时间窗口的时间,默认值 (秒)
 
              type: #可选 限流方式,不选则默认serviceId根据服务进行限流
 
                    - user
 
                    - origin
 
                    - url
 
          policies:
 
                myServiceId: #特定的路由
 
                      limit: 10 #可选- 每个刷新时间窗口对应的请求数量限制
 
                      quota: 1000 #可选-  每个刷新时间窗口对应的请求时间限制(秒)
 
                      refresh-interval: 60 # 刷新时间窗口的时间,默认值 (秒)
 
                      type: #可选 限流方式
 
                          - user
 
                          - origin
 
                          - url

maven配置

spring-cloud-zuul-ratelimit根据不同的maven版本相关配置可能有变化

<dependencies>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
	</dependency>
	
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
	</dependency>
	
	<dependency>
		<groupId>com.marcosbarbero.cloud</groupId>
		<artifactId>spring-cloud-zuul-ratelimit</artifactId>
		<version>2.0.6.RELEASE</version>
	</dependency>
</dependencies>

通过入参自定义key策略

如果希望自定义key,那么可以使用自定义RateLimitKeyGenerator来实现增加自己的策略逻辑
例如:根据不通的name进行判定每个name在一分钟内只允许通过10次
配置rateLimit:

ratelimit: 
    key-prefix: springcloud-book #按粒度拆分的临时变量key前缀
    enabled: true #启用开关
    repository: IN_MEMORY #key存储类型,默认是IN_MEMORY本地内存,此外还有多种形式
    behind-proxy: true #表示代理之后
    default-policy: #全局限流策略,可单独细化到服务粒度
      limit: 10 #在一个单位时间窗口的请求数量
      quota: 1000 #在一个单位时间窗口的请求时间限制
      refresh-interval: 60 #单位时间窗口
      type: 
        - user #可指定用户粒度
        - origin #可指定客户端地址粒度
        - url #可指定url粒度

自定义key实现RateLimitKeyGenerator:

@RequiredArgsConstructor
public class CustomRateLimitKeyGenerator implements RateLimitKeyGenerator {
 
    private final RateLimitProperties properties;
    private final RateLimitUtils rateLimitUtils;
 
    @Override
    public String key(final HttpServletRequest request, final Route route, final Policy policy) {
   		 //policy限流配置中的类型可配置多个,集合方式获取
        final List<Type> types = policy.getType().stream().map(MatchType::getType).collect(Collectors.toList());
        //拼接字符串以冒号分隔
        final StringJoiner joiner = new StringJoiner(":");
        //获取请求中的参数name
        String name=request.getParameter("name");
        //获取配置文件临时变量key前缀properties.getKeyPrefix()
        joiner.add(properties.getKeyPrefix());
        joiner.add(name);
        /**if (route != null) {
            joiner.add(route.getId());
        }
        if (!types.isEmpty()) {
            if (types.contains(Type.URL) && route != null) {
                joiner.add(route.getPath());
            }
            if (types.contains(Type.ORIGIN)) {
                joiner.add(rateLimitUtils.getRemoteAddress(request));
            }
            if (types.contains(Type.USER)) {
                joiner.add(rateLimitUtils.getUser(request));
            }**/
        }
        //转换成字符串形成key返回
        return joiner.toString();
    }
}

限流原理(redis、JPA、Consul)

redis、jpa、concul这三种是通过计数器进行限流,不同的限流策略生成一个key,计算剩余限流相关数据是存入rate中,key-rate一一对应。请求进入后,根据key查找有没有相关rate生成,没有则生成rate保存,后置filter进行更行剩余请求次数,请求耗时。
前置过滤:获取route数据,策略集合,遍历集合,生成限流key,创建rate对象,比较limit请求次数,请求时间是否超出阈值。
后置过滤:计算请求耗时,更新rate对象中的剩余请求次数,请求时间阈值
源码中rate实体类:

public class Rate {
 
    @Id
    @Column(name = "rate_key")
    private String key;
    /**
     * 剩余的请求数
     *
     */
    private Long remaining;
    /**
     * 剩余的请求耗时
     *
     */
    private Long remainingQuota;
    /**
     *
     *
     */
    private Long reset;
    /**
     * 过期时间
     *
     */
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy HH:mm:ss")
    private Date expiration;
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值