当前位置: 首页 > news >正文

高并发系统中的限流与异步优化实战指南

cover

高并发系统中的限流与异步优化实战指南

一、业务场景描述

在某电商平台大促活动中,系统峰值QPS超过5k,库存扣减与订单下单调用下游支付与库存服务节点极易触及瓶颈,导致延迟飙升、接口超时甚至卡死。为确保系统稳定性,需要对外部访问进行精细化限流,并将部分非核心流程异步化,来削峰填谷、提升系统吞吐能力。

二、技术选型过程

  1. 限流:考虑Token Bucket(Guava RateLimiter)、Redis Leaky Bucket、基于Hystrix和Sentinel的熔断限流方案。最终选型:Redis分布式令牌桶+Sentinel链路监控。
  2. 异步:消息中间件对比Kafka和RabbitMQ,因为业务对消息消费顺序无严格要求,且消息量中等,选用RabbitMQ,配合Spring Boot异步注解及线程池处理。

三、实现方案详解

3.1 Redis分布式限流

我们采用Redis脚本在服务器端完成令牌计算,避免多点并发导致的不一致。核心Lua脚本:

-- keys[1]:限流key
-- ARGV[1]:令牌桶最大容量
-- ARGV[2]:每秒填充速率
-- ARGV[3]:当前时间戳(ms)
local key = KEYS[1]
local capacity = tonumber(ARGV[1])
local rate = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local last = tonumber(redis.call('hget', key, 'lastTime') or 0)
local tokens = tonumber(redis.call('hget', key, 'tokens') or capacity)
-- 计算新增令牌
local delta = math.max(0, (now - last) * rate / 1000)
tokens = math.min(capacity, tokens + delta)
if tokens < 1 thenreturn 0
elseredis.call('hset', key, 'tokens', tokens - 1)redis.call('hset', key, 'lastTime', now)return 1
end

对应Java调用:

public boolean tryAcquire(String key) {List<String> keys = Collections.singletonList(key);List<String> args = Arrays.asList("100", "50", String.valueOf(System.currentTimeMillis()));Long result = redisTemplate.execute((RedisCallback<Long>) conn -> {Object nativeRes = conn.eval(luaScript.getBytes(), ReturnType.INTEGER, 1,keys.get(0).getBytes(), args.get(0).getBytes(), args.get(1).getBytes(), args.get(2).getBytes());return (Long) nativeRes;});return Objects.equals(result, 1L);
}

在Spring Boot中,将该方法包装为AOP切面,对订单创建接口进行限流:

@Aspect
@Component
public class RateLimitAspect {@Autowiredprivate RateLimiterService limiter;@Pointcut("@annotation(com.example.annotation.RateLimit)")public void limitPoint(){}@Around("limitPoint() && @annotation(limit)")public Object around(ProceedingJoinPoint pjp, RateLimit limit) throws Throwable {boolean ok = limiter.tryAcquire(limit.key());if (!ok) {throw new RateLimitException("系统繁忙,请稍后重试");}return pjp.proceed();}
}

3.2 RabbitMQ异步处理

对于下单后邮件通知和统计日志等非核心流程,使用RabbitMQ异步解耦。配置示例:

spring:rabbitmq:host: amqp.example.comport: 5672username: userpassword: passlistener:simple:concurrency: 3max-concurrency: 10

生产者代码:

@Autowired
private RabbitTemplate rabbitTemplate;
public void sendOrderEvent(Order order) {rabbitTemplate.convertAndSend("exchange.order", "routing.order", order);
}

消费者代码:

@Component
public class OrderEventListener {@RabbitListener(queues = "queue.order")public void onMessage(Order order) {// 发送邮件通知、写日志emailService.sendConfirmation(order);logService.record(order);}
}

通过异步队列,主流程无需等待邮件和日志写入的完成,QPS可提升30%以上。

3.3 综合优化效果

  • 峰值QPS支撑从5k提高到8k,接口95%响应时间从200ms降至120ms。
  • OOM、超时错误减少80%。

四、踩过的坑与解决方案

  1. Redis脚本超时:排查后发现单脚本执行时间过长,将桶容量和填充速率配置到更合理值,并对热点key做局部缓存降低压力。
  2. RabbitMQ死信堆积:生产环境队列消息堆积未及时消费,增加消费者并发数及监控报警,设置TTL和死信队列进行告警。
  3. 数据一致性:异步场景下,库存扣减与订单创建需强一致,用分布式事务方案会影响性能,改为先同步扣减库存,异步补偿日志。

五、总结与最佳实践

  • 对外请求建议先用多级限流:网关、服务侧、代码内限流。
  • 异步解耦要关注消息可靠性与幂等性,必要时使用幂等标识或全局唯一ID。
  • 监控与报警:实时监控队列长度、限流命中率与接口延时,及时调优。
  • 参数化配置:容量、速率、并发消费数等可热更新,满足不同业务场景。

通过上述限流与异步优化方案,可显著提升高并发系统的稳定性与吞吐能力,适用于电商、金融、社交等多种场景。

http://www.dtcms.com/a/502833.html

相关文章:

  • agent设计模式:第一章节—提示链
  • 【STM32】RTC实时时钟
  • 【数据结构与算法基础】04. 线性表与链表详解(C++ 实战)
  • C程序中的预处理器
  • 长沙黄页全域seo
  • 负载均衡技术:Nginx/HAProxy/F5 等负载均衡配置与优化
  • 外国人做的关于中国的视频网站吗高师院校语言类课程体系改革与建设 教学成果奖申报网站
  • Linux 进阶指令实操指南:文件查看、时间管理、搜索压缩全场景覆盖(附高频案例)
  • K8S(十六)—— K8S集群apiserver证书有效期修改指南(适配v1.20.11版本)
  • Altium Designer(AD24)Reports报告功能总结
  • 第一章 绪论——课后习题解练【数据结构(c语言版 第2版)】
  • Ubuntu 系统 RabbitMQ 安装指南与使用(含 C++ 客户端与 SSL 错误解决)
  • 网站开发外包 价格阿里巴巴国际站入驻费用及条件
  • MVVM架构模式详解:从原理到Android实战
  • 【Pico企业版】Pico企业版的多种Wifi快速连接方式(Pico 4UE的快捷Wifi连接技巧)
  • Kafka服务端处理producer请求原理解析
  • 以电商系统为例,理解用户体验五层模型
  • 兰州网站开发企业学校门户网站建设
  • CreArt2.5.7 | 无限AI图片生成,将文字描述转化为艺术作品
  • Linux企业级解决方案架构:字节跳动短视频推荐系统全链路实践
  • Python编程之常用模块
  • ios面试底层题目
  • h5游戏免费下载:《高达战争》
  • 百度网盘不限速2025年最新方法
  • 网站维护大概要多久学校英文网站建设申请
  • 深入比较 Rust 与 Go:并发时代的两把利剑
  • 容器安全:gVisor系统调用过滤,攻击面缩小?
  • 前端基础二、CSS(二)、CSS基础选择器
  • 学做电影网站asp.net门户网站项目怎么做
  • 云主机搭建多个网站专业型网站网站