使用Redis实现分布式限流

一、限流场景与算法选择

1.1 为什么需要分布式限流

在高并发系统中,API接口的突发流量可能导致服务雪崩。传统的单机限流方案在分布式环境下存在局限,需要借助Redis等中间件实现集群级流量控制。

1.2 令牌桶算法优势

  • 允许突发流量:稳定速率填充令牌,应对合理流量峰值
  • 平滑限流:相比固定窗口算法更细腻的流量控制
  • 弹性调整:动态修改令牌生成速率和桶容量

二、Redis核心实现原理

2.1 数据结构设计

Key: rate_limiter:{service_name}
Value:
{"tokens": 10,      // 当前令牌数"last_time": 1717024000 // 最后更新时间(秒级时间戳)
}

2.2 原子操作保障

使用Redis的Lua脚本保证操作的原子性:

local key = KEYS[1]
local now = tonumber(ARGV[1])
local capacity = tonumber(ARGV[2])
local rate = tonumber(ARGV[3])
local requested = tonumber(ARGV[4])local data = redis.call("HMGET", key, "tokens", "last_time")
local tokens = tonumber(data[1]) or capacity
local last_time = tonumber(data[2]) or nowlocal delta = math.floor((now - last_time) * rate)
if delta > 0 thentokens = math.min(tokens + delta, capacity)last_time = now
endlocal result = 0
if tokens >= requested thentokens = tokens - requestedresult = 1
endredis.call("HMSET", key, "tokens", tokens, "last_time", last_time)
redis.call("EXPIRE", key, 86400)  // 自动过期清理return result

三、Java完整实现代码

3.1 添加依赖(pom.xml)

<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.4.6</version>
</dependency>

3.2 Redis限流器核心类

public class RedisRateLimiter {private final JedisPool jedisPool;private final String serviceKey;private final int capacity;  // 桶容量private final double rate;   // 令牌/秒private static final String LUA_SCRIPT = "..." // 上述Lua脚本public boolean tryAcquire(int permits) {try (Jedis jedis = jedisPool.getResource()) {long now = Instant.now().getEpochSecond();Object result = jedis.eval(LUA_SCRIPT,Collections.singletonList(serviceKey),Arrays.asList(String.valueOf(now),String.valueOf(capacity),String.valueOf(rate),String.valueOf(permits)));return "1".equals(result.toString());}}
}

3.3 使用示例

// 初始化限流器(每秒2个令牌,桶容量10)
RedisRateLimiter limiter = new RedisRateLimiter(jedisPool, "order_api", 10, 2.0);public Response processRequest(Request request) {if (!limiter.tryAcquire(1)) {throw new RateLimitExceededException("请求过于频繁");}// 处理业务逻辑return doBusiness(request);
}

四、高级优化策略

4.1 预热机制

// 冷启动时渐进式填充令牌
private void warmUp() {long warmupPeriod = 30_000; // 30秒预热期double coldFactor = 3; // 冷启动系数double warmupRate = capacity * coldFactor / (warmupPeriod/1000);// 动态调整rate参数...
}

4.2 动态规则配置

// 监听配置中心变更
@NacosConfigListener(dataId = "rate_limit_rules")
public void updateRules(String config) {// 解析JSON配置并更新capacity/rate
}

4.3 多维度限流

-- 在Lua脚本中增加维度参数
local key = "rate_limiter:" .. service_name .. ":" .. user_id

五、生产环境注意事项

  1. Redis集群模式:使用Hash Tag确保相同资源的请求路由到同一节点

    String serviceKey = "{order_api}:" + userId;
    
  2. 性能监控

    redis-cli info stats | grep total_commands_processed
    
  3. 降级策略

    • 快速失败模式(默认)
    • 排队等待模式(配合阻塞队列)
    • 动态降级(根据系统负载自动调整rate)
  4. 异常处理

    try {return tryAcquire(permits);
    } catch (JedisException e) {// Redis不可用时降级为本地限流return localLimiter.tryAcquire();
    }
    

总结

本文实现的Redis分布式限流方案已在多个生产环境验证,支撑百万级QPS的电商系统。建议在实际使用中结合监控告警系统,并建立限流规则评审机制,避免因错误配置影响正常业务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/79279.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

快速搭建WordPress网站的主题

WP快主题(wpkuai.com )是一款由知名WordPress专业团队打造的专业化WordPress主题&#xff0c;旨在让用户使用该wordpress主题快速搭建网站。 WP快主题专注于快速搭建WordPress网站的主题解决方案。其主题设计注重简洁性与高效性&#xff0c;旨在帮助用户快速完成网站的搭建和部…

STM32江科大----------PID算法

声明&#xff1a;本人跟随b站江科大学习&#xff0c;本文章是观看完视频后的一些个人总结和经验分享&#xff0c;也同时为了方便日后的复习&#xff0c;如果有错误请各位大佬指出&#xff0c;如果对你有帮助可以点个赞小小鼓励一下&#xff0c;本文章建议配合原视频使用❤️ 如…

将JSON格式的SQL查询转换为完整SQL语句的实战解析

一、背景与需求 在现代数据处理中,JSON格式因其灵活性和可读性,常被用于定义SQL查询的结构。然而,直接编写JSON格式的SQL指令后,如何将其转换为可执行的SQL语句是开发者常遇到的挑战。本文将通过一个Python函数和多个实际案例,解析如何将JSON结构转换为完整的SQL语句,并…

java CountDownLatch用法简介

CountDownLatch倒计数锁存器 CountDownLatch&#xff1a;用于协同控制一个或多个线程等待在其他线程中执行的一组操作完成&#xff0c;然后再继续执行 CountDownLatch用法 构造方法&#xff1a;CountDownLatch(int count)&#xff0c;count指定等待的条件数&#xff08;任务…

Leetcode - 双周赛135

目录 一、3512. 使数组和能被 K 整除的最少操作次数二、3513. 不同 XOR 三元组的数目 I三、3514. 不同 XOR 三元组的数目 II四、3515. 带权树中的最短路径 一、3512. 使数组和能被 K 整除的最少操作次数 题目链接 本题实际上求的就是数组 nums 和的余数&#xff0c;代码如下&…

【后端】【python】利用反射器----动态设置装饰器

&#x1f4d8; Python 装饰器进阶指南 一、装饰器本质 ✅ 本质概念 Python 装饰器的本质是 函数嵌套 返回函数&#xff0c;它是对已有函数的增强&#xff0c;不修改原函数代码&#xff0c;使用语法糖 decorator 实现包裹效果。 def my_decorator(func):def wrapper(*args, …

Nodejs Express框架

参考&#xff1a;Node.js Express 框架 | 菜鸟教程 第一个 Express 框架实例 接下来我们使用 Express 框架来输出 "Hello World"。 以下实例中我们引入了 express 模块&#xff0c;并在客户端发起请求后&#xff0c;响应 "Hello World" 字符串。 创建 e…

Docker Swarm 集群

Docker Swarm 集群 本文档介绍了 Docker Swarm 集群的基本概念、工作原理以及相关命令使用示例&#xff0c;包括如何在服务调度中使用自定义标签。本文档适用于需要管理和扩展 Docker 容器化应用程序的生产环境场景。 1. 什么是 Docker Swarm Docker Swarm 是用于管理 Docker…

充电宝项目中的MQTT(轻量高效的物联网通信协议)

文章目录 补充&#xff1a;HTTP协议MQTT协议MQTT的核心特性MQTT vs HTTP&#xff1a;关键对比 EMQX项目集成EMQX集成配置客户端和回调方法具体接口和方法处理处理类 补充&#xff1a;HTTP协议 HTTP是一种应用层协议&#xff0c;使用TCP作为传输层协议&#xff0c;默认端口是80…

【iOS】UIPageViewController学习

UIPageViewController学习 前言创建一个UIPageViewController最简单的使用 UIPageViewController的方法说明&#xff1a;效果展示 UIPageViewController的协议方法 前言 笔者最近在写项目时想实现一个翻书效果&#xff0c;上网学习到了UIPageViewController今天写本篇博客总结…

Linux搭建环境:从零开始掌握基础操作(四)

​ ​ 您好&#xff0c;我是程序员小羊&#xff01; 前言 软件测试第一步就是搭建测试环境&#xff0c;如何搭建好测试环境&#xff0c;需要具备两项的基础知识&#xff1a; 1、Linux 命令: 软件测试第一个任务, 一般都需要进行环境搭建, 一部分&#xff0c;环境搭建内容是在服…

一天一个java知识点----Tomcat与Servlet

认识BS架构 静态资源&#xff1a;服务器上存储的不会改变的数据&#xff0c;通常不会根据用户的请求而变化。比如&#xff1a;HTML、CSS、JS、图片、视频等(负责页面展示) 动态资源&#xff1a;服务器端根据用户请求和其他数据动态生成的&#xff0c;内容可能会在每次请求时都…

YOLOV8 OBB 海思3516训练流程

YOLOV8 OBB 海思3516训练流程 目录 1、 下载带GPU版本的torch(可选) 1 2、 安装 ultralytics 2 3、 下载pycharm 社区版 2 4、安装pycharm 3 5、新建pycharm 工程 3 6、 添加conda 环境 4 7、 训练代码 5 9、配置Ymal 文件 6 10、修改网络结构 9 11、运行train.py 开始训练模…

【深度学习】花书第18章——配分函数

直面配分函数 许多概率模型&#xff08;通常是无向图模型&#xff09;由一个未归一化的概率分布 p ~ ( x , θ ) \tilde p(\mathbf x,\theta) p~​(x,θ)定义。我们必须通过除以配分函数 Z ( θ ) Z(\pmb{ \theta}) Z(θ)来归一化 p ~ \tilde p p~​。以获得一个有效的概率分…

工作记录1

日常总结、灵感记录、学习要点。持续记录 学海无涯,再好的记性也比不过烂笔头,记录一下学习日常、灵感、要点。 前言:最近看见一个博文,很有感触,是某个大佬自己运营的网站,分享了他的各种经验文章和自身的一些笔记。本人还没有他这么屌,所以还是先在CSDN上小试牛刀吧…

Spring Boot(二十一):RedisTemplate的String和Hash类型操作

RedisTemplate和StringRedisTemplate的系列文章详见&#xff1a; Spring Boot&#xff08;十七&#xff09;&#xff1a;集成和使用Redis Spring Boot&#xff08;十八&#xff09;&#xff1a;RedisTemplate和StringRedisTemplate Spring Boot&#xff08;十九&#xff09;…

智能指针之设计模式1

本文探讨一下智能指针和GOF设计模式的关系&#xff0c;如果按照设计模式的背后思想来分析&#xff0c;可以发现围绕智能指针的设计和实现有设计模式的一些思想体现。当然&#xff0c;它们也不是严格意义上面向对象的设计模式&#xff0c;毕竟它们没有那么分明的类层次体系&…

中间件--ClickHouse-1--基础介绍(列式存储,MPP架构,分布式计算,SQL支持,向量化执行,亿万级数据秒级查询)

1、概述 ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS)。它由俄罗斯的互联网巨头Yandex为解决其内部数据分析需求而开发&#xff0c;并于2016年开源。专为大规模数据分析&#xff0c;实时数据分析和复杂查询设计&#xff0c;具有高性能、实时数据和可扩展性等…

Go之Slice和数组:深入理解底层设计与最佳实践

在Go语言中&#xff0c;数组&#xff08;Array&#xff09;和切片&#xff08;Slice&#xff09;是两种看似相似却本质不同的数据结构。本文将深入剖析它们的底层实现机制&#xff0c;并结合实际代码示例&#xff0c;帮助开发者掌握核心差异和使用场景。 一、基础概念&#xff…

力扣热题100——普通数组(不普通)

普通数组但一点不普通&#xff01; 最大子数组和合并区间轮转数组除自身以外数组的乘积缺失的第一个正数 最大子数组和 这道题是非常经典的适用动态规划解决题目&#xff0c;但同时这里给出两种解法 动态规划、分治法 那么动态规划方法大家可以在我的另外一篇博客总结中看到&am…