java B2B2C springmvc mybatis多租戶電子商城系統-gateway 限流

it小飛俠的微博發表於2019-04-09

Spring Cloud Gateway限流

在Spring Cloud Gateway中,有Filter過濾器,因此可以在“pre”型別的Filter中自行實現上述三種過濾器。需要JAVA Spring Cloud大型企業分散式微服務雲構建的B2B2C電子商務平臺原始碼 一零三八七七四六二六,但是限流作為閘道器最基本的功能,Spring Cloud Gateway官方就提供了RequestRateLimiterGatewayFilterFactory這個類,適用Redis和lua指令碼實現了令牌桶的方式。

具體原始碼不打算在這裡講述,讀者可以自行檢視,程式碼量較少,先以案例的形式來講解如何在Spring Cloud Gateway中使用內建的限流過濾器工廠來實現限流。

首先在工程的pom檔案中引入gateway的起步依賴和redis的reactive依賴,程式碼如下:


 <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifatId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

複製程式碼

在配置檔案中做以下的配置:


server:
  port: 8081
spring:
  cloud:
    gateway:
      routes:
      - id: limit_route
        uri: http://httpbin.org:80/get
        predicates:
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]
        filters:
        - name: RequestRateLimiter
          args:
            key-resolver: '#{@hostAddrKeyResolver}'
            redis-rate-limiter.replenishRate: 1
            redis-rate-limiter.burstCapacity: 3
  application:
    name: gateway-limiter
  redis:
    host: localhost
    port: 6379
    database: 0


複製程式碼

在上面的配置檔案,指定程式的埠為8081,配置了 redis的資訊,並配置了RequestRateLimiter的限流過濾器,該過濾器需要配置三個引數:

burstCapacity,令牌桶總容量。

replenishRate,令牌桶每秒填充平均速率。

key-resolver,用於限流的鍵的解析器的 Bean 物件的名字。它使用 SpEL 表示式根據#{@beanName}從 Spring 容器中獲取 Bean 物件。

KeyResolver需要實現resolve方法,比如根據Hostname進行限流,則需要用hostAddress去判斷。實現完KeyResolver之後,需要將這個類的Bean註冊到Ioc容器中。


public class HostAddrKeyResolver implements KeyResolver {

    @Override
    public Mono<String> resolve(ServerWebExchange exchange) {
        return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
    }

}

 @Bean
    public HostAddrKeyResolver hostAddrKeyResolver() {
        return new HostAddrKeyResolver();
    }

複製程式碼

可以根據uri去限流,這時KeyResolver程式碼如下:


public class UriKeyResolver  implements KeyResolver {

    @Override
    public Mono<String> resolve(ServerWebExchange exchange) {
        return Mono.just(exchange.getRequest().getURI().getPath());
    }

}

 @Bean
    public UriKeyResolver uriKeyResolver() {
        return new UriKeyResolver();
    }

 

複製程式碼

也可以以使用者的維度去限流:


   @Bean
    KeyResolver userKeyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
    }


複製程式碼

用jmeter進行壓測,配置10thread去迴圈請求lcoalhost:8081,迴圈間隔1s。從壓測的結果上看到有部分請求通過,由部分請求失敗。通過redis客戶端去檢視redis中存在的key。如下:

2279594-8b25dea450dbd070.png
可見,RequestRateLimiter是使用Redis來進行限流的,並在redis中儲存了2個key。

java B2B2C springmvc mybatis多租戶電子商城系統 

相關文章