
V1.x 系列:单体应用
V1.0: 丢失更新+锁失效
- 目标: 实现最基础的秒杀下单功能 (Spring Boot + MySQL)。
- 遇到问题: JMeter 一压测,立刻出现丢失更新问题,即订单数为200,但库存数只减少了20。尝试 synchronized(因 AOP 代理失效),最终采用 ReentrantLock + 手动编程式事务。
- 逻辑链: 功能实现 -> 暴露丢失更新问题 -> JUC锁 -> 深入理解 Spring AOP 事务原理 -> 解决数据一致性
V1.1: 读写分离
- 目标: 解决 V1.1 中“查询库存”也被锁住,导致性能低下的问题。
- 手段: 引入 ReentrantReadWriteLock。
- 逻辑链: 性能瓶颈 -> 读写分离
V1.2: 流量控制
- 目标:在进入核心业务逻辑之前,先进行流量控制,只允许有限数量的请求进入,从而保护系统不被瞬时流量冲垮。
- 手段:加入semaphore信号量。
- 逻辑链: 读写锁导致“写”瓶颈 -> 线程排队耗尽资源 -> 引入 Semaphore 限流 -> 保护应用不被瞬时流量冲垮
V1.3 异步处理和优化
- 目标: 解决用户请求必须同步等待数据库写入,响应时间太长(“转圈圈”)的问题,并进一步压榨单体性能。
- 手段:
- 引入 ThreadPoolExecutor 和 BlockingQueue,将下单操作异步化。
- 1 使用原子化SQL (UPDATE…WHERE) 替代 ReentrantLock。 2 增加内存售罄标记 (volatile)。
- 逻辑链:
- 响应时间瓶颈 -> 异步解耦 -> 提升用户体验
- Java层锁的瓶颈 -> 下推到数据库层(原子SQL) -> 彻底释放应用服务器性能
- 在此期间,被迫解决了 Java Agent 守护线程、异步异常捕获等一系列深层次问题,为后续升级打下了坚实基础。
V2.x 引入中间件
V2.0: 引入 Redis
- 目标: V1.4 的瓶颈最终变成了数据库的磁盘I/O。
- 手段: 将核心战场(库存、用户判重)从“慢速”的 MySQL 转移到“极速”的内存 Redis。使用 Lua 脚本保证原子性。
- 逻辑链: 数据库I/O瓶颈 -> 引入内存数据库 -> 性能数量级提升
V2.1: 引入 RabbitMQ
- 目标: 解决 V2.0 中,JVM 内存队列 (BlockingQueue) 在应用崩溃时会丢失订单消息的致命缺陷。
- 手段: 用专业的外部消息队列 RabbitMQ 替换 BlockingQueue。
- 逻辑链: 数据丢失风险 -> 引入消息中间件 -> 保证消息的可靠持久化
- 在此期间,解决了默认的转化器能力非常有限,不知道如何处理自定义的SeckillOrder类的问题,手动配置一个更强大的JSON序列化转换器。
V2.2: 引入 Redis Sentinel
- 目标: 解决 V2.0 中,Redis 成为新的单点故障 (SPOF) 的问题。
- 手段: 搭建 Redis Sentinel (哨兵) 高可用集群(一主二从三哨兵)。
- 逻辑链: 新单点故障 -> 引入高可用方案 -> 验证自动故障转移
- 在此期间,花费大量时间尝试解决 Docker 内部网络的各种疑难杂症,最终只能单独验证Redis Sentinel的自动故障转移功能。
V2.3: 引入 Prometheus + Grafana
- 目标: 解决 V2.2 带来的“黑盒子”问题。系统虽然在运行,但看不见其内部状态。
- 手段: 引入 Actuator + Prometheus + Grafana 监控体系。
- 逻辑链: 系统黑盒 -> 引入宏观监控 -> 实现可观测性(Metrics)
V3.x 系列:加固系统
V3.0: 引入 Resilience4j
- 目标: 解决 V2.1 中,下游依赖(MySQL)故障,会导致消费者线程全部阻塞,进而引发雪崩效应的问题。
- 手段: 为 OrderConsumerService 引入 @CircuitBreaker (熔断器)。
- 逻辑链: 雪崩风险 -> 引入服务保护 -> 实现弹性与优雅降级
- 在此期间,解决了 AOP 注解优先级(@Transactional 高于 @CircuitBreaker)导致的熔断器不生效问题。
V3.1: Nginx 接入层限流
- 目标: 解决 V3.0 中,应用服务器(Tomcat)本身在面对海量流量时,会因线程池耗尽而成为第一道瓶颈的问题。
- 手段: 引入 Nginx 作为最前端的接入层网关,并配置 limit_req (限流)。
- 逻辑链: 应用层瓶颈 -> 引入接入层网关 -> 实现多层流量防护
V3.2: 手写 Java Agent
- 目标: 为了给 V3.3(SkyWalking)打基础,决定“造轮子”,深入理解 APM 工具的底层原理。
- 手段: 创建一个独立的 mini-apm-agent 项目,使用 javaagent 和 Byte Buddy 对 seckill-app 进行无侵入的方法耗时监控。
- 逻辑链: 知其然 -> 知其所以然 -> 深入 JVM 字节码 -> 掌握 APM 原理
V3.3: 引入 SkyWalking
- 目标: 解决 V2.3 (Prometheus) 只能“宏观”看指标,无法“微观”诊断单次慢请求的问题。
- 手段: 引入 SkyWalking 实现全链路追踪。
- 逻辑链: 宏观监控的局限 -> 引入微观追踪(Tracing) -> 获得全链路性能“瀑布图”
- (成果): 通过追踪图,我们定量地看到了“消息队列排队时间”(如7.6秒),为我们下一步的 V4.0 拆分提供了数据驱动的决策依据。