一、pom依赖
java
<!--限流器-->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-ratelimiter</artifactId>
<version>1.7.0</version>
</dependency>
二、限流器配置
java
package com.test.config;
import io.github.resilience4j.ratelimiter.RateLimiter;
import io.github.resilience4j.ratelimiter.RateLimiterConfig;
import io.github.resilience4j.ratelimiter.RateLimiterRegistry;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
@Configuration
public class RateConfig {
@Value("${ratelimit.qps.handshake:100}")
private int handshakeQps; // 默认QPS 100
@Value("${ratelimit.qps.msg:5000}")
private int msgQps; // 默认QPS 5000
//3s内只能发送一次请求
@Bean(name = "test")
public RateLimiter test() {
RateLimiterConfig rateLimiterConfig = RateLimiterConfig.custom()
.timeoutDuration(Duration.ofMillis(0)) // 不等待 直接失败
.limitRefreshPeriod(Duration.ofMillis(3000)) // 表示每隔多长时间刷新一次限流计数器 这里3s
.limitForPeriod(1) // 一个限流周期内允许的最大请求数 这里1次
.build();
return RateLimiterRegistry.of(rateLimiterConfig).rateLimiter("handshake");
}
//握手的限流策略(0.1s内允许10个握手连接)
@Bean(name = "handshake")
public RateLimiter handshakeRateLimiter() {
int tenMillis = 10; // 时间单位同时除 10
RateLimiterConfig config = RateLimiterConfig.custom()
.timeoutDuration(Duration.ofMillis(0)) // 不等待 直接失败
.limitRefreshPeriod(Duration.ofMillis(1000 / tenMillis)) // 按 100ms 刷新 更平滑
.limitForPeriod(handshakeQps / tenMillis) // 平均 QPS
.build();
return RateLimiterRegistry.of(config).rateLimiter("handshake");
}
//发送消息的限流策略(0.1s内允许发送500个消息)
@Bean(name = "sendMsg")
public RateLimiter sendMsgRateLimiter() {
int tenMillis = 10; // 时间单位同时除 10
RateLimiterConfig config = RateLimiterConfig.custom()
.timeoutDuration(Duration.ofMillis(0)) // 不等待 直接失败
.limitRefreshPeriod(Duration.ofMillis(1000 / tenMillis)) // 按 100ms 刷新 更平滑
.limitForPeriod(msgQps / tenMillis) // 平均 QPS
.build();
return RateLimiterRegistry.of(config).rateLimiter("sendMsg");
}
}
三、限流器使用
java
@RestController
public class TestController {
@Resource(name = "test")
RateLimiter test;
@Resource(name = "handshake")
RateLimiter handshake;
@Resource(name = "sendMsg")
RateLimiter sendMsg;
@GetMapping("/test")
public String test() {
boolean b1 = test.acquirePermission();
boolean b2 = handshake.acquirePermission();
boolean b3 = sendMsg.acquirePermission();
System.out.println("sendMsg: " + b1 + " handshake: " + b2 + " sendMsg: " + b3);
return "test";
}
}