记录一下java接口限流的方法。
Java 中实现接口限流可以通过多种方式,这里介绍两种常见的方法: 1、使用 Guava RateLimiter 2、使用 Redis 来实现。 先来看使用Guava RateLimiter怎么实现,我给一个小例子。 直接上代码。
使用 Guava RateLimiter:
Guava 提供了一个名为 RateLimiter 的工具类,可以实现基于令牌桶算法的限流。下面是一个简单的示例:
public class RateLimiterExample {
private static final RateLimiter rateLimiter = RateLimiter.create(10); // 设置每秒允许的最大请求数量为 10
public void processRequest(String userId) {
boolean acquired = rateLimiter.tryAcquire();
if (acquired) {
System.out.println("Request accepted for user " + userId);
// 处理请求...
} else {
System.out.println("Request rejected for user " + userId);
// 拒绝请求...
}
}
}
// 使用示例
RateLimiterExample example = new RateLimiterExample();
example.processRequest("user1"); // 请求接受
example.processRequest("user2"); // 请求接受
example.processRequest("user3"); // 请求接受
example.processRequest("user4"); // 请求接受
example.processRequest("user5"); // 请求接受
example.processRequest("user6"); // 请求接受
example.processRequest("user7"); // 请求接受
example.processRequest("user8"); // 请求接受
example.processRequest("user11"); // 请求拒绝
使用 Redis 来实现:
如果应用是分布式部署的,可以使用 Redis 来实现分布式限流。这里使用 Redis 的 INCR 和 EXPIRE 命令配合 Lua 脚本来实现漏桶算法的限流。
首先,安装 Redis 并启动服务。然后,你可以使用 Jedis 或 Lettuce 等库来操作 Redis。
public class RedisRateLimiter {
private static final int MAX_REQUESTS_PER_SECOND = 10; // 最大每秒请求数量
private static final long TIME_WINDOW_IN_SECONDS = 1; // 时间窗口长度(单位:秒)
public boolean tryProcessRequest(String userId) {
Jedis jedis = new Jedis("localhost", 6379);
String script = "local currentRequests = redis.call('incr', KEYS[1])\n"
+ "if currentRequests == 1 then\n"
+ "redis.call('expire', KEYS[1], ARGV[1])\n"
+ "end\n"
+ "return tonumber(currentRequests) <= tonumber(ARGV[2])";
Long result = (Long) jedis.eval(script, Collections.singletonList(userId), Arrays.asList(TIME_WINDOW_IN_SECONDS + "", MAX_REQUESTS_PER_SECOND + ""));
return result != null && result > 0;
}
}
// 使用示例
RedisRateLimiter limiter = new RedisRateLimiter();
limiter.tryProcessRequest("user1"); // 请求接受
limiter.tryProcessRequest("user2"); // 请求接受
limiter.tryProcessRequest("user3"); // 请求接受
limiter.tryProcessRequest("user4"); // 请求接受
limiter.tryProcessRequest("user5"); // 请求接受
limiter.tryProcessRequest("user6"); // 请求接受
limiter.tryProcessRequest("user7"); // 请求接受
limiter.tryProcessRequest("user8"); // 请求接受
limiter.tryProcessRequest("user9"); // 请求接受
limiter.tryProcessRequest("user10"); // 请求接受
limiter.tryProcessRequest("user11"); // 请求拒绝
这两种方法都可以实现接口限流,选择哪种取决于你的需求和应用场景。对于简单场景,Guava RateLimiter 已经足够;对于分布式系统,使用 Redis 实现的限流方案更为合适。