java网关限流_网关限流使用
### POM 依賴
這里一定要注意,是網關引入的redis-reactive,背壓模式的redis。
```
org.springframework.boot
spring-boot-starter-data-redis-reactive
```
#### 配置按照請求IP 的限流
```
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: lb://pigx-upms
order: 10000
predicates:
- Path=/admin/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1 # 令牌桶的容積
redis-rate-limiter.burstCapacity: 3 # 流速 每秒
key-resolver: "#{@remoteAddrKeyResolver}" #SPEL表達式去的對應的bean
- StripPrefix=1
```
- 配置bean,多維度限流量的入口 對應上邊key-resolver 【我自己哦
```
/**
* 自定義限流標志的key,多個維度可以從這里入手
* exchange對象中獲取服務ID、請求信息,用戶信息等
*/
@Bean
KeyResolver remoteAddrKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}
```
OK 完成。
#### 壓力測試
并發5個線程。

#### Redis 數據變化
我們使用redis的**monitor** 命令,實時查看redis 的操作情況。
會發現在redis中會操作兩個key
- request_rate_limiter.{xxx}.timestamp
- request_rate_limiter.{xxx}.tokens

### 實現原理

Spring Cloud Gateway 默認實現 Redis限流,如果擴展只需要實現ratelimter接口即可。
### RedisRateLimter 的核心代碼,判斷是否取到令牌的實現,通過調用 redis的LUA 腳本。
```
public Mono isAllowed(String routeId, String id) {
Config routeConfig = getConfig().getOrDefault(routeId, defaultConfig);
int replenishRate = routeConfig.getReplenishRate();
int burstCapacity = routeConfig.getBurstCapacity();
try {
List keys = getKeys(id);
returns unixtime in seconds.
List scriptArgs = Arrays.asList(replenishRate + "", burstCapacity + "",
Instant.now().getEpochSecond() + "", "1");
// 這里是核心,執行redis 的LUA 腳本。
Flux> flux =
this.redisTemplate.execute(this.script, keys, scriptArgs);
return flux.onErrorResume(throwable -> Flux.just(Arrays.asList(1L, -1L)))
.reduce(new ArrayList(), (longs, l) -> {
longs.addAll(l);
return longs;
}) .map(results -> {
boolean allowed = results.get(0) == 1L;
Long tokensLeft = results.get(1);
Response response = new Response(allowed, getHeaders(routeConfig, tokensLeft));
if (log.isDebugEnabled()) {
log.debug("response: " + response);
}
return response;
});
}
catch (Exception e) {
log.error("Error determining if user allowed from redis", e);
}
return Mono.just(new Response(true, getHeaders(routeConfig, -1L)));
}
```
#### LUA 腳本

總結
以上是生活随笔為你收集整理的java网关限流_网关限流使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 图像处理 空白_使用Java进
- 下一篇: java swt 菜鸟教程_编程基础学习