О свинье:
На основе Spring Cloud и oAuth2.0 разработана платформа разработки, основанная на разделении передней и задней части Vue, которая поддерживает различные входы в систему, такие как учетная запись, SMS и SSO, и предоставляет вспомогательные учебные пособия по разработке видео.
Адрес облака кода:gitee.com/log4j/pig
О Spring Cloud Gateway
SpringCloudGateway — это официальный шлюз, разработанный Spring на основе таких технологий, как Spring 5.0, Spring Boot 2.0 и Project Reactor. Spring Cloud Gateway призван предоставить простой и эффективный способ маршрутизации API. Spring Cloud Gateway как шлюз в экосистеме Spring Cloud нацелен наАльтернатива Netflix ZUUL, который не только обеспечивает унифицированный метод маршрутизации, но и обеспечивает базовые функции шлюза на основе метода цепочки фильтров, такие как: безопасность, мониторинг/покупка и ограничение тока.
Как zuul реализует многомерное ограничение тока, смотрите в моем блоге
Zuul: многомерное ограничение тока для построения шлюзов высокой доступности
Начать регулирование шлюза
POM-зависимости
<!--spring cloud gateway依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--基于 reactive stream 的redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
Настройка регулирования по 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,多个维度可以从这里入手
* exchange对象中获取服务ID、请求信息,用户信息等
*/
@Bean
KeyResolver remoteAddrKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}
ОК, чтобы завершить.
испытание давлением
5 потоков одновременно.
Изменения данных Redis
мы используем редисmonitorКоманда для просмотра работы Redis в режиме реального времени.
Вы обнаружите, что в Redis будут работать два ключа.
- request_rate_limiter.{xxx}.timestamp
- request_rate_limiter.{xxx}.tokens
Принцип реализации
Spring Cloud Gateway по умолчанию реализует ограничение тока Redis.Если вы расширите его, вам нужно будет реализовать только интерфейс ratelimter.
Основной код RedisRateLimter определяет, получен ли токен путем вызова LUA-скрипта redis.
public Mono<Response> isAllowed(String routeId, String id) {
Config routeConfig = getConfig().getOrDefault(routeId, defaultConfig);
int replenishRate = routeConfig.getReplenishRate();
int burstCapacity = routeConfig.getBurstCapacity();
try {
List<String> keys = getKeys(id);
returns unixtime in seconds.
List<String> scriptArgs = Arrays.asList(replenishRate + "", burstCapacity + "",
Instant.now().getEpochSecond() + "", "1");
// 这里是核心,执行redis 的LUA 脚本。
Flux<List<Long>> flux =
this.redisTemplate.execute(this.script, keys, scriptArgs);
return flux.onErrorResume(throwable -> Flux.just(Arrays.asList(1L, -1L)))
.reduce(new ArrayList<Long>(), (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)));
}