使用redis中的zset实现滑动窗口限流

使用redis和zset实现滑动窗口限流

文章目录

Zset

Redis的ZSet(有序集合)可以很好地用来实现滑动窗口限流。滑动窗口限流是一种常见的流量控制方法,它限制了在一定时间窗口内的请求数量。下面是使用Redis ZSet实现滑动窗口限流的一个简单示例:

初始化一个ZSet:其中包含所有用户的ID和时间戳。

java 复制代码
ZSet<String> zset = redisTemplate.opsForZSet().create("rateLimiter");

添加元素到ZSet:当用户发起请求时,将当前时间戳和用户ID作为元素添加到ZSet中。

java 复制代码
long currentTimeMillis = System.currentTimeMillis();
String userId = "user1";
redisTemplate.opsForZSet().add("rateLimiter", userId, currentTimeMillis);

删除过期的元素:为了保持滑动窗口的大小,需要删除超出时间窗口范围的元素。例如,如果滑动窗口的大小为60秒,那么需要删除60秒之前添加的元素。

java 复制代码
long windowSizeInSeconds = 60;
long currentTimeMillis = System.currentTimeMillis();
// 获取ZSet中所有元素
List<ZSetElement<String>> elements = redisTemplate.opsForZSet().reverseRangeWithScores("rateLimiter", 0, -1);
for (ZSetElement<String> element : elements) {
    long elementTimestamp = element.getScore();
    if (currentTimeMillis - elementTimestamp > windowSizeInSeconds * 1000) {
        redisTemplate.opsForZSet().remove("rateLimiter", element.getValue());
    }
}

检查是否超过限制:在添加新元素后,检查ZSet的大小是否超过限制。如果超过限制,则拒绝请求。

java 复制代码
int limit = 100; // 每分钟的请求限制
long size = redisTemplate.opsForZSet().size("rateLimiter");
if (size >= limit) {
    // 超过限制,拒绝请求...
}

注意,以上代码是基于Java的Spring Data Redis实现,如果你使用其他语言的Redis客户端,代码可能会有所不同,但基本的思路是相同的。此外,这个简单的实现没有考虑分布式环境下的限流,这需要额外的同步机制。

拓展补充

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

@Component
public class ApiCallCounter {

    private static final String API_CALLS = "api_calls:";

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public void incrementApiCallCount(String apiName) {
        String key = API_CALLS + apiName + ":current";
        redisTemplate.opsForValue().increment(key);
    }
}

在上述代码中,我们定义了一个ApiCallCounter类,用于计数接口调用量。当接口被调用时,我们使用incrementApiCallCount方法增加计数。该方法使用RedisTemplateopsForValue().increment方法对指定键进行递增操作。我们使用一个包含API名称和时间戳的键来存储每分钟的调用量。例如,如果API名称为exampleApi并且当前时间是2023年7月19日10点05分,则键将是api_calls:exampleApi:current:202307191005

相关推荐
Seven977 分钟前
剑指offer-31、整数中1出现的次数
redis
RestCloud14 小时前
SQL Server到Hive:批处理ETL性能提升30%的实战经验
数据库·api
RestCloud15 小时前
为什么说零代码 ETL 是未来趋势?
数据库·api
ClouGence17 小时前
CloudCanal + Paimon + SelectDB 从 0 到 1 构建实时湖仓
数据库
DemonAvenger1 天前
NoSQL与MySQL混合架构设计:从入门到实战的最佳实践
数据库·mysql·性能优化
AAA修煤气灶刘哥1 天前
别让Redis「歪脖子」!一次搞定数据倾斜与请求倾斜的捉妖记
redis·分布式·后端
AAA修煤气灶刘哥1 天前
后端人速藏!数据库PD建模避坑指南
数据库·后端·mysql
RestCloud2 天前
揭秘 CDC 技术:让数据库同步快人一步
数据库·api
得物技术2 天前
MySQL单表为何别超2000万行?揭秘B+树与16KB页的生死博弈|得物技术
数据库·后端·mysql
christine-rr2 天前
linux常用命令(4)——压缩命令
linux·服务器·redis