共计 1855 个字符,预计需要花费 5 分钟才能阅读完成。
背景痛点:高并发下的系统瓶颈
在 ClawHub 技能发布系统中,我们遇到了典型的流量突增问题。当有热门技能发布时,系统 QPS(Queries Per Second)会从平时的 200 左右突然飙升到 5000+,这导致了一系列问题:

- 任务丢失 :约 15% 的发布请求因服务超时而丢失
- 缓存雪崩 :Redis 集群在高峰期出现连接瓶颈,导致缓存命中率下降至 65%
- 数据库压力 :MySQL 连接池经常爆满,平均响应时间从 50ms 恶化到 1200ms
技术选型对比
消息队列方案
- RabbitMQ 优势 :
- 内置 Dead Letter Exchange(DLX 死信交换机)机制,天然支持任务重试
- 更轻量级的协议,适合我们的中等吞吐量场景(约 5k-10k QPS)
-
完善的 Web 管理界面,便于运维监控
-
Kafka 劣势 :
- 需要额外开发死信队列功能
- 我们的场景不需要日志级别的持久化存储
缓存方案
- 本地缓存(Caffeine):
- 适合高频访问且很少变更的数据
-
我们用于存储技能分类等基础数据
-
分布式缓存(Redis):
- 用于库存扣减等需要强一致性的场景
- 通过 Lua 脚本保证原子性操作
核心实现
RabbitMQ 延迟队列配置
@Configuration
public class RabbitMQConfig {
// 1. 声明死信交换机
@Bean
public DirectExchange dlxExchange() {return new DirectExchange("dlx.exchange");
}
// 2. 配置监听器容器
@Bean
public SimpleRabbitListenerContainerFactory retryContainerFactory(ConnectionFactory connectionFactory) {SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setConcurrentConsumers(10); // 并发消费者数
return factory;
}
}
Redis Lua 脚本实现
-- KEYS[1]: 库存 key
-- ARGV[1]: 扣减数量
local stock = tonumber(redis.call('GET', KEYS[1]))
if stock >= tonumber(ARGV[1]) then
return redis.call('DECRBY', KEYS[1], ARGV[1])
else
return -1
end
调用示例:
String script = "... 上述 Lua 脚本...";
Long result = (Long) jedis.eval(
script,
Collections.singletonList("stock:skill_123"),
Collections.singletonList("1")
);
避坑指南
分布式锁的注意事项
- TTL 设置 :
- 必须设置合理的过期时间(建议 5 -10 秒)
- 过短会导致业务未完成就释放锁
-
过长会影响系统可用性
-
续期问题 :
- 考虑使用 Redisson 的 watchDog 机制自动续期
- 避免因 GC 停顿导致锁意外失效
事务一致性方案
我们采用本地消息表 + 定时任务补偿的方案:
- 业务操作与消息记录在同一个 DB 事务中
- 后台线程每分钟扫描未确认的消息
- 对失败消息进行有限次重试(通常 3 次)
验证指标
JMeter 压测配置
- 线程组 :
- 初始线程数:100
- 每 30 秒增加 100 线程
-
最大线程数:1000
-
关键指标 :
- 错误率 <0.1%
- 平均响应时间 <500ms
GC 日志分析
优化前:
[GC (Allocation Failure) [PSYoungGen: 614400K->52376K(716800K)]
优化后:
[GC (Allocation Failure) [PSYoungGen: 614400K->10240K(716800K)]
延伸思考
熔断降级方案
可以考虑集成 Hystrix:
- 在技能详情查询接口设置熔断阈值
- 当错误率超过 5% 时自动降级
- 返回缓存中的历史数据或默认值
Serverless 架构
对于流量波动大的活动页面:
- 适合使用 AWS Lambda 或阿里云函数计算
- 但核心交易链路仍需保持常驻服务
总结
通过本次优化,我们实现了:
- 发布成功率提升至 99.99%
- 高峰期响应时间降低 80%
- 服务器成本节省 40%
关键经验是:根据业务特点选择技术方案,不盲目追求新技术。下次我们会尝试将部分非核心功能迁移到 Serverless 架构。
正文完
