IT评测·应用市场-qidao123.com技术社区

标题: 如何用Redis实现限流? [打印本页]

作者: 北冰洋以北    时间: 2024-12-10 13:46
标题: 如何用Redis实现限流?

如何用Redis实现限流?

目次


什么是限流?

限流是指在各种应用场景中,通过技术和计谋手段对数据流量、请求频率或资源斲丧进行有筹划的限制,以避免体系负载过高、性能降落甚至崩溃的情况发生。限流的目的在于维护体系的稳定性和可用性,并确保服务质量。
限流的意义

使用限流有以下几个利益:
限流常见算法

限流的常见实现算法有以下几个:
使用Redis实现限流

计数器算法

此方法的实现思路是:使用一个计数器存储当前请求量(每次使用incr方法相加),并设置一个过期时间,计数器在一定时间内自动清零。
具体实现代码如下:
  1. import redis.clients.jedis.Jedis;
  2. public class RedisRateLimiter {
  3.     private static final String REDIS_KEY = "request_counter";
  4.     private static final int REQUEST_LIMIT = 100; // 限流阈值
  5.     private static final int EXPIRE_TIME = 60; // 过期时间(秒)
  6.     public boolean allowRequest() {
  7.         Jedis jedis = new Jedis("localhost");
  8.         
  9.         try {
  10.             Long counter = jedis.incr(REDIS_KEY);
  11.             if (counter == 1) {
  12.                 // 第一次设置过期时间
  13.                 jedis.expire(REDIS_KEY, EXPIRE_TIME);
  14.             }
  15.             
  16.             if (counter <= REQUEST_LIMIT) {
  17.                 return true; // 允许请求通过
  18.             } else {
  19.                 return false; // 请求达到限流阈值,拒绝请求
  20.             }
  21.         } finally {
  22.             jedis.close();
  23.         }
  24.     }
  25.     public static void main(String[] args) {
  26.         RedisRateLimiter rateLimiter = new RedisRateLimiter();
  27.         for (int i = 0; i < 110; i++) {
  28.             if (rateLimiter.allowRequest()) {
  29.                 System.out.println("Request Allowed");
  30.             } else {
  31.                 System.out.println("Request Denied (Rate Limited)");
  32.             }
  33.         }
  34.     }
  35. }
复制代码
滑动窗口算法

此方法的实现思路是:将请求都存入到ZSet集合中,在分数(score)中存储当前请求时间。然后再使用ZSet提供的range方法容易的获取到2个时间戳内的全部请求,通过获取的请求数和限流数进行比较并判断,从而实现限流。
具体实现代码如下:
  1. import redis.clients.jedis.Jedis;
  2. import redis.clients.jedis.Tuple;
  3. import java.util.Set;
  4. public class RedisSlidingWindowRateLimiter {
  5.     private static final String ZSET_KEY = "request_timestamps";
  6.     private static final int WINDOW_SIZE = 60; // 时间窗口大小(单位:秒)
  7.     private static final int REQUEST_LIMIT = 100; // 限流阈值
  8.     public boolean allowRequest() {
  9.         Jedis jedis = new Jedis("localhost");
  10.         long currentTimestamp = System.currentTimeMillis() / 1000;
  11.         // 添加当前请求的时间戳到有序集合
  12.         jedis.zadd(ZSET_KEY, currentTimestamp, String.valueOf(currentTimestamp));
  13.         // 移除过期的请求时间戳,保持时间窗口内的请求
  14.         long start = currentTimestamp - WINDOW_SIZE;
  15.         long end = currentTimestamp;
  16.         jedis.zremrangeByScore(ZSET_KEY, 0, start);
  17.         // 查询当前时间窗口内的请求数量
  18.         Set<Tuple> requestTimestamps = jedis.zrangeByScoreWithScores(ZSET_KEY, start, end);
  19.         long requestCount = requestTimestamps.size();
  20.         jedis.close();
  21.         // 判断请求数量是否超过限流阈值
  22.         return requestCount <= REQUEST_LIMIT;
  23.     }
  24.     public static void main(String[] args) {
  25.         RedisSlidingWindowRateLimiter rateLimiter = new RedisSlidingWindowRateLimiter();
  26.         for (int i = 0; i < 110; i++) {
  27.             if (rateLimiter.allowRequest()) {
  28.                 System.out.println("Request Allowed");
  29.             } else {
  30.                 System.out.println("Request Denied (Rate Limited)");
  31.             }
  32.         }
  33.     }
  34. }
复制代码
漏桶算法

漏桶算法的实现思路是:使用一个固定容量的桶来存储请求,请求以固定的速率被处理。如果桶满了,新的请求将被丢弃。
令牌桶算法

令牌桶算法的实现思路是:有一个固定速率填充令牌的桶,令牌代表请求许可。当请求到达时,需要从桶中取出一个令牌,如果桶中有令牌则允许请求通过,否则拒绝。桶的容量是有限的,多余的令牌会被丢弃。
Redis限流的实践案例

在现实应用中,Redis限流可以应用于多个场景,比方API调用频率限制、用户举动监控、服务降级等。以下是一些实践案例:
总结

Redis作为一个高性能的键值存储体系,在限流方面有着广泛的应用。通过使用不同的限流算法,如计数器算法、滑动窗口算法、漏桶算法和令牌桶算法,我们可以有用地控制请求流量,保护体系稳定性,优化用户体验,并低沉运维成本。每种算法都有其适用场景和优缺点,选择合适的限流计谋需要根据具体的业务需求和体系特点来决定。通过合理配置和优化,Redis可以帮助我们实现高效、稳定的限流办理方案。
在现实应用中,限流计谋的选择和实现需要综合思量业务特点、体系架构和性能要求。比方,在面对高并发、高流量的场景时,可能需要采用更复杂的限流算法和计谋,

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4