RocketMQ进阶08:流量控制机制 - 保护系统的最后防线

引言:为什么需要流量控制? 防止系统过载: Consumer处理速度:100条/秒 消息生产速度:1000条/秒 结果:消息堆积 → 内存溢出 → 系统崩溃 Producer端限流 // 设置发送超时 producer.setSendMsgTimeout(3000); // 异步发送队列大小限制 producer.setMaxMessageSize(4 * 1024 * 1024); // 4MB Consumer端限流 // 1. 限制拉取数量 consumer.setPullBatchSize(32); // 每次最多拉32条 // 2. 限制并发消费线程 consumer.setConsumeThreadMin(20); consumer.setConsumeThreadMax(20); // 3. 限制消费速率 consumer.setPullInterval(100); // 拉取间隔100ms Broker端流控 触发条件: 1. 内存使用超过85% 2. 消息堆积超过阈值 3. PageCache繁忙 流控动作: - 拒绝Producer发送 - 降低Consumer拉取频率 本文关键词:流量控制 限流 背压 系统保护

2025-11-14 · maneng

为什么需要熔断限流?从一次生产事故说起

核心观点: 熔断限流不是性能优化,而是系统稳定性的生命线。本文从一次真实生产事故出发,深度剖析为什么微服务架构必须要有熔断限流机制。 引子:2024年11月11日,一次惊心动魄的生产事故 事故背景 某电商平台,日常订单量10万单/天,流量1000 QPS。2024年双十一活动,预计流量增长3-5倍。技术团队提前扩容服务器,增加数据库连接池,准备迎接流量高峰。 然而,谁也没想到,活动开始仅10分钟,整个系统就崩溃了。 时间线复盘 10:00:00 - 活动正式开始 运营团队启动促销活动,用户涌入。前端监控显示流量快速攀升: 10:00:00 → 1,000 QPS(正常) 10:02:00 → 3,000 QPS(预期内) 10:05:00 → 8,000 QPS(超预期) 10:08:00 → 12,000 QPS(远超预期) 10:05:30 - 第一个异常信号 监控系统开始报警: [ALERT] 订单服务响应时间: 50ms → 800ms (P99) [ALERT] 订单服务线程池占用: 50/200 → 180/200 技术团队看到告警,以为是正常的流量压力,决定继续观察。 10:07:15 - 雪崩的开始 [CRITICAL] 订单服务响应时间: 800ms → 5000ms (P99) [CRITICAL] 订单服务线程池占用: 200/200 (100%,线程池耗尽) [ERROR] 用户服务调用超时: connection timeout after 5s 技术团队意识到不对劲,开始排查。日志显示: java.net.SocketTimeoutException: Read timed out at UserServiceClient.getUser(UserServiceClient.java:45) at OrderService.createOrder(OrderService.java:87) ... 原因找到了:用户服务的数据库出现慢查询(某个未加索引的查询,平时10ms,高峰期变成5秒)。 ...

2025-11-03 · maneng

限流算法深度解析:从计数器到令牌桶

核心观点: 限流算法不是单纯的技术选择,而是业务需求与技术约束的权衡。本文从一个真实需求的演进过程出发,深度剖析5种限流算法的设计思路、实现细节和适用场景。 引子:一个API接口的限流需求演进 需求背景 你是某电商平台的后端工程师,负责维护商品查询接口 /api/products/{id}。 初始状态(无限流): @RestController public class ProductController { @Autowired private ProductService productService; @GetMapping("/api/products/{id}") public Result getProduct(@PathVariable Long id) { Product product = productService.getById(id); return Result.success(product); } } 系统运行良好,日常流量500 QPS,数据库和服务器完全可以承受。 第一次危机:流量突增 某天,运营部门做了一个促销活动,流量突然涨到5000 QPS(10倍)。 后果: 10:00:00 - 活动开始,流量5000 QPS 10:00:30 - 数据库连接池耗尽(最大连接数100) 10:01:00 - 响应时间从50ms暴增到5秒 10:01:30 - 服务器CPU 100%,系统崩溃 CTO找你谈话: “给这个接口加个限流,最多支持1000 QPS。” 你的第一反应:计数器! 需求演进1:固定窗口计数器 需求: 每秒最多1000个请求。 你快速实现了一个固定窗口计数器: public class FixedWindowRateLimiter { private final int maxRequests; private final AtomicInteger counter = new AtomicInteger(0); private volatile long windowStart = System.currentTimeMillis(); public FixedWindowRateLimiter(int maxRequests) { this.maxRequests = maxRequests; } public boolean tryAcquire() { long now = System.currentTimeMillis(); // 新窗口,重置计数器 if (now - windowStart >= 1000) { synchronized (this) { if (now - windowStart >= 1000) { counter.set(0); windowStart = now; } } } // 当前窗口未超限 return counter.incrementAndGet() <= maxRequests; } } 部署上线,问题解决!系统稳定运行。 ...

2025-11-03 · maneng

限流算法:固定窗口、滑动窗口与令牌桶

限流算法对比 算法 实现难度 精确度 内存占用 适用场景 固定窗口 简单 低 低 粗粒度限流 滑动窗口 中等 高 中 精确限流 漏桶 中等 高 中 流量整形 令牌桶 复杂 高 中 允许突发 1. 固定窗口算法 原理:时间窗口内计数,超过限制则拒绝 @Service public class FixedWindowRateLimiter { @Autowired private RedisTemplate<String, String> redis; // 限流检查 public boolean isAllowed(String key, int limit, int windowSeconds) { String counterKey = key + ":" + (System.currentTimeMillis() / 1000 / windowSeconds); Long current = redis.opsForValue().increment(counterKey); if (current == 1) { redis.expire(counterKey, windowSeconds, TimeUnit.SECONDS); } return current != null && current <= limit; } } // 使用示例 public boolean checkLimit(String userId) { return rateLimiter.isAllowed("api:user:" + userId, 100, 60); // 每分钟100次 } 问题:临界问题 ...

2025-01-21 · maneng

什么是流量控制?从12306抢票说起

引言:一张春运火车票背后的技术博弈 每年春节前夕,亿万中国人都会参与一场没有硝烟的战争——春运抢票。 2024年春运首日,12306网站的访问量在开售瞬间达到每秒1400万次。这是什么概念?相当于全国1/100的人在同一秒钟点击同一个网站。如果没有任何保护机制,这样的流量洪峰足以在几秒钟内压垮任何系统。 但12306并没有崩溃。用户虽然排队等待,但系统始终稳定运行,每秒稳定处理数十万笔订单。这背后,就是流量控制的功劳。 今天,我们从这个真实场景出发,深入理解什么是流量控制,为什么需要流量控制,以及流量控制在现代微服务架构中的重要性。 一、现实世界的流量控制:无处不在的智慧 在深入技术细节之前,让我们先看看身边的流量控制案例。你会发现,流量控制是人类应对资源有限性的普遍智慧。 1.1 高速公路收费站:削峰填谷 春节自驾回家,你一定遇到过收费站前的长龙。为什么要设置收费站?除了收费,更重要的作用是流量控制。 入口匝道信号灯:红灯时车辆等待,绿灯时放行,确保主路不拥堵 ETC车道与人工车道:快速通道和慢速通道分离,提高整体通行效率 应急车道管制:拥堵时临时开放,增加通行能力 这些措施的本质是:在有限的道路资源下,控制车流速度,避免拥堵导致整体瘫痪。 1.2 景区限流:保护体验与安全 故宫每天限流8万人,黄山限流5万人。为什么要限流? 安全因素:超过承载能力会导致踩踏事故 体验保护:人山人海时,游客体验极差 资源保护:过度使用会损坏文物和生态 这里的流量控制策略更加精细: 预约制:提前规划,错峰入园 分时限流:上午下午分别限制人数 动态调整:根据实时人数关闭入口 1.3 电梯承载限制:刚性约束 电梯标注"限乘13人或1000kg"。这是最简单粗暴的流量控制: 硬性限制:超载则无法运行 即时生效:没有等待队列,超载必须减员 安全优先:宁可降低效率,也要保证安全 1.4 共同规律:资源有限,需求无限 仔细观察,这些案例都有三个共同特征: 资源有限:道路宽度、景区容量、电梯承重 需求波动:高峰期需求远超平时 控制策略:通过限制、排队、拒绝等手段保护系统 这就是流量控制的本质:在资源有限的前提下,通过合理的策略,保证系统稳定运行,并尽可能提升整体效率。 二、软件系统为什么需要流量控制 2.1 12306的技术挑战 回到12306抢票场景,让我们分析一下技术挑战: 正常时期(非春运): 日均访问量:1亿次 峰值QPS:约10万/秒 系统资源:1000台服务器 春运开抢瞬间: 瞬时访问量:每秒1400万次(140倍流量洪峰) 如果不限流:需要14万台服务器(不现实) 实际策略:限流 + 排队 + 分流 2.2 不做流量控制的后果 假设12306不做任何流量控制,会发生什么? 第1秒:1400万请求涌入 网络带宽打满(假设1Gbps,每个请求1KB,需要11.2Gbps) 服务器CPU飙升到100% 数据库连接池耗尽(配置1000个连接,但有140万个并发请求) 第2秒:系统开始崩溃 大量请求超时,用户疯狂刷新 流量不降反升(重试风暴) 数据库响应时间从10ms变成10秒 第3秒:雪崩效应 数据库连接堆积,内存溢出 服务器宕机,用户看到502错误 整个系统彻底瘫痪 恢复时间:可能需要数小时 清理堆积的请求 重启所有服务 用户信任度严重受损 2.3 流量控制的三大目标 通过12306的案例,我们可以总结出流量控制的三大核心目标: ...

2025-01-21 · maneng

如约数科科技工作室

浙ICP备2025203501号

👀 本站总访问量 ...| 👤 访客数 ...| 📅 今日访问 ...