共计 1456 个字符,预计需要花费 4 分钟才能阅读完成。
背景痛点
Allegro Skill 论坛在用户量突破 50 万后,峰值 QPS 达到 1200 时出现明显性能瓶颈:

- 首页接口平均响应时间从 200ms 飙升至 1.2s
- MySQL CPU 利用率长期高于 90%
- 促销活动期间出现多次 504 超时
通过 APM 工具定位到三大核心问题:
- 商品详情页 SQL 存在 N + 1 查询(单次请求触发 28 次商品属性查询)
- 用户会话数据直接写入主库
- 抢购业务使用数据库行锁导致大量线程阻塞
技术选型
架构对比
| 维度 | 单体架构 | 微服务架构 |
|---|---|---|
| 开发效率 | 高 | 中(需处理分布式问题) |
| 容错能力 | 单点故障影响全局 | 故障隔离 |
| 扩展性 | 垂直扩展成本高 | 按服务水平扩展 |
选择 Spring Cloud Alibaba 方案的核心考量:
- Nacos 同时支持服务发现和配置中心,降低运维复杂度
- Sentinel 对突发流量的控制比 Hystrix 更精细化
- Seata 的 AT 模式适合论坛中 80% 的弱事务场景
核心实现
分布式锁实现
// 使用 Redisson 实现抢购幂等性控制
public boolean purchase(Long itemId, Long userId) {RLock lock = redissonClient.getLock("item_lock:" + itemId);
try {
// 尝试加锁,等待 100ms,锁自动释放时间 30s
if (lock.tryLock(100, 30000, TimeUnit.MILLISECONDS)) {
// 查询库存需加分布式锁
ItemStock stock = stockMapper.selectById(itemId);
if (stock.getCount() > 0) {return stockMapper.reduceStock(itemId) > 0;
}
}
} finally {lock.unlock();
}
return false;
}
缓存分层策略
# Redis 配置示例
spring:
redis:
time-to-live: 3600000 # 基础 TTL 1 小时
layered-ttl:
hot: 1800000 # 热点数据 30 分钟
normal: 7200000 # 普通数据 2 小时
cold: 86400000 # 冷数据 24 小时
削峰架构设计
graph TD
A[用户请求] --> B[RabbitMQ 主队列]
B --> C{处理成功?}
C -->| 是 | D[完成订单]
C -->| 否 | E[死信队列]
E --> F[延迟 5 分钟重试]
F --> B
性能验证
压测环境配置:
- 8 核 16G 服务器 × 3
- Redis Cluster 6 节点
- JMeter 500 并发线程
| 场景 | 优化前 TP99 | 优化后 TP99 | 吞吐量提升 |
|---|---|---|---|
| 商品详情页 | 1200ms | 230ms | 4.2 倍 |
| 用户登录 | 800ms | 150ms | 5.3 倍 |
| 秒杀下单 | 超时率 32% | 超时率 0.7% | 36 倍 |
避坑指南
缓存穿透应对
- 布隆过滤器拦截无效 ID
- 空值缓存设置短 TTL(示例:
cache.put(null, 60))
消息积压处理
- 动态扩容消费者实例
- 死信队列设置多级延迟(1s/5s/30s)
- 监控大盘设置堆积阈值告警
分布式事务
- 普通消息使用本地消息表
- 资金操作使用 Seata AT 模式
- 日志类数据采用最终一致性
延伸思考
在 618 大促期间,我们尝试将部分服务迁移到阿里云 FC:
- 优势:弹性扩容速度从 5 分钟缩短到 30 秒
- 挑战:冷启动时延最高达 1.8s(需配合预留实例)
- 成本:突发流量下比 ECS 节省 37% 费用
建议流量模式符合以下特征时考虑 Serverless:
- 业务存在明显的波峰波谷
- 单次请求处理时间短于 3 秒
- 无状态服务占比高
通过本次架构升级,我们总结出高并发系统设计的黄金三角原则:缓存分级、异步解耦、弹性扩展。下一步计划探索 Service Mesh 在全链路灰度发布中的应用。
正文完
发表至: 未分类
近两天内
