随笔 - 76  文章 - 0  评论 - 2  阅读 - 58193

spring cloud gateway(三、实现限流)

限流一般有两个实现方式,令牌桶和漏桶

金牌桶是初始化令牌(容器)的个数,通过拿走里边的令牌就能通过, 没有令牌不能报错,可以设置向容器中增加令牌的速度和最大个数

漏桶是向里边放入请求,当请求数量达到最大值后,丢弃,漏桶中的数据以一定速度流出,没有则不流出

金牌桶实现方式如下:

pom

<dependency>
<groupId>com.github.vladimir-bukhtoyarov</groupId>
<artifactId>bucket4j-core</artifactId>
<version>4.0.0</version>
</dependency>

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

创建下边类并且继承下边类 

public class LimitFilter implements GatewayFilter, Ordered {

private final Logger logger = LoggerFactory.getLogger(LimitFilter.class);

int capacity;
int refillTokens;
Duration refillDuration;

public LimitFilter(int capacity, int refillTokens, Duration refillDuration) {
this.capacity = capacity;
this.refillTokens = refillTokens;
this.refillDuration = refillDuration;
}

private static final Map<String,Bucket> CACHE = new ConcurrentHashMap<>();
private Bucket createNewBucket() {
Refill refill = Refill.of(refillTokens,refillDuration);
Bandwidth limit = Bandwidth.classic(capacity,refill);
return Bucket4j.builder().addLimit(limit).build();
}

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String ip = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
Bucket bucket = CACHE.computeIfAbsent(ip,k -> createNewBucket());
logger.info("IP: " + ip + ",TokenBucket Available Tokens: " + bucket.getAvailableTokens());
if (bucket.tryConsume(1)) {
return chain.filter(exchange);
} else {
exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
return exchange.getResponse().setComplete();
}

}

@Override
public int getOrder() {
return 0;
}
}

配置路由

  @Bean
public RouteLocator customerRouteLocator(RouteLocatorBuilder builder) {
// @formatter:off
return builder.routes()
.route(r -> r.path("/consulserver/**")
.filters(f -> f.stripPrefix(1)
.filter(new LimitFilter(10,1,Duration.ofSeconds(1))))
.uri("lb://consulserver")
.order(0)
.id("throttle_customer_service")
).build();
// @formatter:on

 原文:https://blog.csdn.net/m0_37834471/article/details/82621353


redis限流原文:https://blog.csdn.net/ifrozen/article/details/80016566 

posted on   ttke  阅读(4029)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示