21,Zuul:构建高可用网关之多维度限流

原文:Zuul:构建高可用网关之多维度限流

对请求的目标URL进行限流(例如:某个URL每分钟只允许调用多少次)
对客户端的ip进行限流(例如: 对某个Ip每分钟只允许请求多少次)
对某些特定用户或者用户组进行限流(例如: 非vip用户限制每分钟只允许滴哦阿勇100次某个API等)
对维度混合的限流。此时,就需要实现一些限流规则的编排机制。与,或,非等关系
介绍
spring-cloud-zuul-ratelimit是和zuul整合提供分布式限流策略的扩展,只需在yaml中配置几行配置,就可使应用支持限流

<dependency>
    <groupId>com.marcosbarbero.cloud</groupId>
    <artifactId>spring-cloud-zuul-ratelimit</artifactId>
    <version>1.3.4.RELEASE</version>
</dependency>

支持限流的粒度
服务粒度(默认配置,当前服务模块的限流控制)
用户粒度(详细说明,见文本总结)
ORIGIN粒度(用户请求的origin作为粒度控制)
接口粒度(请求接口的地址作为粒度控制)
以上粒度自由组合,有支持多种情况
如果还不够,自定义RateLimiKeyGenerator实现。

//默认实现
public String key(final HttpServletRequest request, final Route route, final RateLimitProperties.Policy policy) {
    final List<Type> types = policy.getType();
    final StringJoiner joiner = new StringJoiner(":");
    joiner.add(properties.getKeyPrefix());
    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(getRemoteAddr(request));
        }
        // 这个结合文末总结。
        if (types.contains(Type.USER)) {
            joiner.add(request.getUserPrincipal() != null ? request.getUserPrincipal().getName() : ANONYMOUS_USER);
        }
    }
    return joiner.toString();
}

InMemoryRateLimiter - 使用 ConcurrentHashMap作为数据存储
ConsulRateLimiter - 使用 Consul 作为数据存储
RedisRateLimiter - 使用 Redis 作为数据存储
SpringDataRateLimiter - 使用 数据库 作为数据存储

限流的配置
limit单位时间内允许访问的个数
quota 单位时间内允许访问的总时间(统计每次请求的时间总和)
refresh-interval 单位时间设置

zuul:
   ratelimit:
      key-prefix:  your-prefix
      enabled: true
      repository: REDIS
      behind-proxy: true
      prolicies:
         myServiceId:
                 limit: 10
                 quota: 20
                 refresh-interval: 30
                 type:
                       -user

以上配置的意思是:30秒内允许10个访问,或者总请求时间小于20秒、、


效果展示
application.yml

zuul:
  ratelimit:
    key-prefix: pig-ratelimite 
    enabled: true 
    repository: REDIS 
    behind-proxy: true
    policies:
      pig-admin-service:
        limit: 2
        quota: 1
        refresh-interval: 3
   

Redis 中数据结构 注意红色字体

总结

  • 可以使用Spring Boot Actuator 提供的服务状态,动态设置限流开关
  • 源码可以参考:https://gitee.com/log4j/pig
  • 用户限流的实现:如果你的项目整合 Shiro 或者 Spring Security 安全框架,那么会自动维护request域UserPrincipal,如果是自己的框架,请登录成功后维护request域UserPrincipal,才能使用用户粒度的限流,未登录默认是:anonymous。具体代码实现可以看 DefaultRateLimitKeyGenerator,type为USER的实现
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章