Zuul:構建高可用網關之多維度限流

  • 對請求的目標URL進行限流(例如:某個URL每分鐘只容許調用多少次)
  • 對客戶端的訪問IP進行限流(例如:某個IP每分鐘只容許請求多少次)
  • 對某些特定用戶或者用戶組進行限流(例如:非VIP用戶限制每分鐘只容許調用100次某個API等)
  • 多維度混合的限流。此時,就須要實現一些限流規則的編排機制。與、或、非等關係。

介紹

spring-cloud-zuul-ratelimit是和zuul整合提供分佈式限流策略的擴展,只需在yaml中配置幾行配置,就可以使應用支持限流git

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

支持的限流粒度

  • 服務粒度 (默認配置,當前服務模塊的限流控制)github

  • 用戶粒度 (詳細說明,見文末總結)spring

  • ORIGIN粒度 (用戶請求的origin做爲粒度控制)數據庫

  • 接口粒度 (請求接口的地址做爲粒度控制)安全

  • 以上粒度自由組合,又能夠支持多種狀況。bash

  • 若是還不夠,自定義RateLimitKeyGenerator實現。數據結構

//默認實現
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();
}
複製代碼

支持的存儲方式

image

  • InMemoryRateLimiter - 使用 ConcurrentHashMap做爲數據存儲
  • ConsulRateLimiter - 使用 Consul 做爲數據存儲
  • RedisRateLimiter - 使用 Redis 做爲數據存儲
  • SpringDataRateLimiter - 使用 數據庫 做爲數據存儲

限流配置

  • limit 單位時間內容許訪問的個數
  • quota 單位時間內容許訪問的總時間(統計每次請求的時間綜合)
  • refresh-interval 單位時間設置
zuul:
  ratelimit:
    key-prefix: your-prefix 
    enabled: true 
    repository: REDIS 
    behind-proxy: true
    policies:
      myServiceId:
        limit: 10
        quota: 20
        refresh-interval: 30
        type:
          - user
        
複製代碼

以上配置意思是:30秒內容許10個訪問,而且要求總請求時間小於20秒框架

效果展現

yaml配置:分佈式

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

動態圖 ↓↓↓↓↓ 字體

image

Redis 中數據結構 注意紅色字體

image

總結

  • 能夠使用Spring Boot Actuator 提供的服務狀態,動態設置限流開關
  • 源碼能夠參考:gitee.com/log4j/pig
  • 用戶限流的實現:若是你的項目整合 Shiro 或者 Spring Security 安全框架,那麼會自動維護request域UserPrincipal,若是是本身的框架,請登陸成功後維護request域UserPrincipal,才能使用用戶粒度的限流。未登陸默認是:anonymous
相關文章
相關標籤/搜索