记录一下java接口限流的方法。

118 阅读2分钟

记录一下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 的 INCREXPIRE 命令配合 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 实现的限流方案更为合适。