1. 促销秒杀流量暴增,Redis 缓存雪崩,导致数据库被压垮
案例:
- 在双 11 促销活动中,某爆款商品库存信息存储在 Redis,但因 Redis 集群某个主节点宕机,导致所有查询回退到数据库,MySQL 和 TiDB 被打爆,订单服务不可用。
原因分析:
- 缓存雪崩:高并发查询缓存时,Redis 挂掉,所有流量直接冲击数据库。
- 缓存击穿:热门商品的 Redis 缓存突然失效,导致瞬间大量查询穿透到数据库。
- 缓存穿透:攻击者或大量无效查询请求查询数据库中不存在的数据,导致数据库负载过高。
- Redis 主从延迟:高并发写入导致主从同步延迟,查询命中从库的老数据,影响用户体验。
紧急补救方案(生产环境应对):
- 快速恢复 Redis:如果是 Redis 宕机,立即重启实例,或通过 Redis Sentinel/Cluster 切换主节点。
- 限流降级:使用 Nginx / Sentinel / Resilience4j 进行限流,降低对数据库的直接冲击。
- 热点 Key 预加载:手动回填缓存,避免数据库成为瓶颈。
- 业务降级:临时采用静态缓存,如 CDN 直接返回库存数据。
长期解决方案(架构优化):
✅ 缓存预热:在活动开始前,提前加载热点商品数据到 Redis,避免冷启动问题。
✅ 分布式缓存+本地缓存双层架构:采用 Caffeine + Redis 组合,提高热点 Key 查询效率。
✅ Redis 降级策略:采用 Multi-Level Caching 方案,热点数据缓存到多个层级,避免单点压力。
✅ 分布式限流:利用 令牌桶 / 漏桶算法 限制高并发请求流量,防止 Redis 再次雪崩。
✅ 数据库层面优化:MySQL + TiDB 读写分离,热点数据存入 TiDB,保障高可用性。
2. RocketMQ 消息堆积,导致订单系统卡死
案例:
- 由于某次支付服务升级,RocketMQ 的订单消费速度远低于消息生产速度,导致订单消息队列消息大量积压,最终 RocketMQ Broker 宕机,订单处理延迟 10+ 分钟。
原因分析:
- 消费者消费速率低,导致未能及时处理积压的消息。
- 网络抖动或 Broker 负载过高,导致消息未能正确分发。
- 消息重试机制问题,导致消费失败的消息被多次重试,增加压力。
紧急补救方案(生产环境应对):
- 扩容消费者:手动增加 Consumer Group 的实例数,提高消费吞吐量。
- 调整消费模式:将 Pull 模式改为 Push,提高消费效率。
- 手动批量消费:调大批量消费参数
consumeMessageBatchMaxSize
,加速消息处理。 - 临时消息清理:对于无关紧要的消息,人工手动丢弃部分积压的消息,防止系统彻底崩溃。
长期解决方案(架构优化):
✅ 异步批量消费:批量拉取消息,避免逐条消费带来的性能损耗。
✅ 死信队列(DLQ):将消费失败的消息存入死信队列,避免无限重试导致消息堆积。
✅ RocketMQ 分片消费:增加 Topic 分区,提高并行消费能力。
✅ 使用 Kafka 替代 RocketMQ(大流量业务):Kafka 适用于超大并发场景,可用性比 RocketMQ 高。
3. Kubernetes 自动扩容失败,导致服务实例崩溃
案例:
- 618 促销期间,用户量暴增,Kubernetes 自动扩容(HPA)失败,导致应用实例 CPU 飙升至 100%,最终服务不可用。
原因分析:
- HPA 配置不合理,未正确设置
targetCPUUtilizationPercentage
,导致扩容不及时。 - Pod 启动慢,由于容器镜像过大或初始化逻辑复杂,导致扩容延迟。
- 集群资源不足,导致 Kubernetes 无法再调度新的实例。
紧急补救方案(生产环境应对):
- 手动扩容:通过
kubectl scale deployment
强制扩容服务实例。 - 快速重启异常 Pod:删除高负载 Pod,确保流量能分发到正常 Pod。
- 流量降级:关闭部分非核心功能,释放计算资源。
长期解决方案(架构优化):
✅ 提前压测扩容策略,在高峰前进行 K8s 负载测试,确保 HPA 触发时间足够早。
✅ 使用 KEDA 替代 HPA,KEDA 能基于消息队列、Kafka 等外部事件触发扩容,比 HPA 更灵活。
✅ 优化容器启动时间,精简应用启动逻辑,减少 Pod 启动时间,避免扩容延迟。
✅ 合理设置 Pod 资源限制,防止某些 Pod 过度占用 CPU / 内存,影响整体扩容能力。
好的!我再补充几个更深度的生产事故分析,涵盖 TiDB、MySQL、微服务调用链、分布式事务、数据库死锁 等更复杂的场景,确保你在面试中展现真正的架构师思维。
4. TiDB 读写分离导致数据不一致
案例:
- 订单系统采用 TiDB 进行数据存储,并配置了 TiDB Follower 只读 模式来分担数据库压力,但在高并发场景下,用户提交订单后立即查询订单状态,发现返回的是旧数据,导致 订单状态错误,用户投诉。
原因分析:
- TiDB 的 Follower 读是异步复制,主库(Leader)写入后,Follower 可能存在一定的同步延迟,导致查询时读到旧数据。
- 高并发场景下 Leader 负载过高,请求被调度到 Follower,但 Follower 数据未同步,导致数据不一致。
- 分布式事务导致数据提交时间不同,部分 TiDB Region 延迟提交,出现短时间内的数据可见性问题。
紧急补救方案(生产环境应对):
- 强制所有查询走 Leader:临时修改服务代码,增加
set tidb_replica_read = 'leader'
,确保查询数据的最新状态。 - 手动调整 Follower 复制延迟:降低
txn-commit-timestamp
的延迟值,加速数据同步。 - 回滚影响数据:如果部分订单状态错误,手动执行 SQL 修正订单状态。
长期解决方案(架构优化):
✅ 延迟敏感的业务强制走 Leader 读:对于涉及资金结算、订单状态等数据,查询时加 FOR UPDATE
或者 set tidb_replica_read = 'leader'
。
✅ 缓存订单状态:使用 Redis 缓存用户的订单状态,避免 TiDB 读取旧数据。
✅ 优化 TiDB 事务提交:确保事务提交后能快速同步至 Follower,降低复制延迟。
✅ TiDB + MySQL 组合架构:对于强一致性要求的核心业务(如支付、订单),使用 MySQL,其他流量继续走 TiDB。
5. MySQL 高并发导致数据库死锁
案例:
- 在大促期间,多个用户同时提交订单,订单系统写入 MySQL 的
order
和order_item
表时,出现死锁,导致部分订单写入失败,业务异常。
原因分析:
- 事务并发执行时,更新相同的行,导致行级锁(InnoDB 采用 MVCC+行锁)。
- 索引设计问题,未命中索引导致 间隙锁(Gap Lock),多个事务互相等待。
- 悲观锁 + 高并发,多个事务同时
SELECT FOR UPDATE
,导致事务互相等待,进入死锁状态。
紧急补救方案(生产环境应对):
- 手动杀死死锁事务:查询
SHOW ENGINE INNODB STATUS
,找出死锁事务,执行KILL <thread_id>
终止事务。 - 调整死锁超时时间:修改
innodb_lock_wait_timeout=3
,减少事务等待时间,避免业务长时间卡死。 - 降级为 Redis 预扣库存:将库存检查和订单创建拆分,避免订单写入直接锁定 MySQL。
长期解决方案(架构优化):
✅ 降低事务粒度:拆分大事务,减少一次性锁定的数据量。
✅ 避免全表扫描锁表:确保查询命中索引,减少意外的 间隙锁 和 行锁 竞争。
✅ 乐观锁替代悲观锁:采用版本号(version
字段)+ WHERE version = ?
的方式控制并发更新。
✅ 数据库分库分表:通过 Sharding 方案(MyCat、ShardingSphere),分散高并发写入压力。
6. 分布式事务异常,导致订单支付状态丢失
案例:
- 在订单支付流程中,涉及 订单系统(MySQL)、支付系统(TiDB) 和 库存系统(Redis),采用 RocketMQ + 事务消息 进行跨服务事务控制,但因某次支付超时,支付状态未正确回调,导致用户扣款但订单状态未更新。
原因分析:
- RocketMQ 事务消息未正确回查,导致事务补偿机制未生效,订单状态未更新。
- 多个数据库(MySQL + TiDB)事务一致性问题,导致部分数据提交成功,但部分失败。
- 分布式锁超时,导致订单状态更新未能成功提交,出现数据丢失。
紧急补救方案(生产环境应对):
- 手动触发 RocketMQ 事务回查,确保支付成功的事务状态被正确回补。
- 查询支付网关,手动补充支付回调,修正订单状态。
- 数据库人工修复,对异常订单进行数据修复,确保用户体验不受影响。
长期解决方案(架构优化):
✅ 使用 Seata 进行分布式事务管理:通过 Seata AT/TCC/XA 模式实现事务一致性。
✅ 事务消息 + 补偿机制:确保 RocketMQ 事务消息能够回查,避免事务丢失。
✅ 设计幂等机制:确保支付状态更新是幂等操作,避免重复扣款或丢失状态。
✅ 可靠事件表(Eventual Consistency):在订单数据库中增加 transaction_log
表,确保事务最终一致性。
7. Kubernetes 网络抖动,导致微服务调用失败
案例:
- 某次集群升级时,部分 Pod 迁移至新的 Node,导致服务 DNS 解析失败,所有微服务互相调用失败,导致整个系统短暂性不可用。
原因分析:
- Kubernetes CoreDNS 服务异常,Pod 无法正确解析 Service 的 Cluster IP。
- Pod 迁移导致网络连接断开,TCP 连接未能正确重建,导致服务短暂不可用。
- Istio 服务网格异常,导致流量路由错误,部分服务无法访问。
紧急补救方案(生产环境应对):
- 重启 CoreDNS,确保 DNS 解析恢复。
- 手动更新 DNS 缓存,在 Pod 内执行
nslookup
或dig
确保 DNS 解析正确。 - 强制 Pod 重启,确保新的网络连接能正确建立。
长期解决方案(架构优化):
✅ CoreDNS 高可用部署,确保多个 DNS 实例可用,避免单点故障。
✅ 应用级 DNS 缓存,使用 Nginx 或 Envoy 进行短时间的 DNS 缓存,提高解析稳定性。
✅ Kubernetes 网络策略优化,避免跨 Node 迁移导致流量中断。
✅ Service Mesh 监控,使用 Istio / Linkerd 监控服务调用情况,提前发现问题。
确认支付成功的订单,并手动修正订单状态,避免用户投诉。
- 重新执行幂等性更新,确保数据库事务不会因为重复执行而产生脏数据。
长期解决方案(架构优化):
✅ 使用 Seata 处理分布式事务:Seata AT 模式适用于 MySQL,保证全局事务一致性。
✅ 事务补偿机制(TCC 方案):在支付回调失败时,手动触发 Try-Confirm-Cancel 补偿逻辑。
✅ 消息可靠性增强:引入 RocketMQ 事务消息 + 事务状态回查机制,确保支付状态不会丢失。
✅ 幂等性保证:所有涉及分布式事务的接口必须保证 幂等性,避免重复执行导致的数据错误。
8. 微服务间调用链路过长,导致超时和雪崩
案例:
- 用户下单后,订单系统需要调用 库存服务、支付服务 和 物流服务,但因网络延迟,部分请求超时,导致订单提交失败。
- 进一步分析发现,调用链路超过 6 层服务,每个接口响应时间均在 200ms~500ms,导致总延迟超过 3s,最终用户体验极差。
原因分析:
- 服务链路过长:服务 A → B → C → D → E → F,每个调用增加了额外的网络和处理延迟。
- 无熔断机制:某个依赖服务(如物流服务)超时,导致整个订单流程被阻塞。
- 同步调用过多:所有服务均为同步 REST 调用,未使用异步消息或事件驱动架构。
紧急补救方案(生产环境应对):
- 降级非核心服务:如果物流服务不可用,订单仍然可以提交,稍后补充物流信息。
- 手动限流:使用 Sentinel 进行限流,避免服务间过载导致集体雪崩。
- 请求超时调整:缩短 HTTP 请求超时,避免长时间等待影响主业务流程。
长期解决方案(架构优化):
✅ 减少调用层级:将高频交互的服务合并,如 库存+订单 整合为单一原子操作。
✅ 使用异步架构:采用 Kafka / RocketMQ 事件驱动,减少同步调用的阻塞时间。
✅ 引入熔断机制:Spring Cloud Resilience4j 或 Sentinel 进行熔断,防止级联故障。
✅ 请求缓存:如订单查询请求,可直接从 Redis 读取,而非每次都调用订单服务。
9. K8s 节点故障,导致部分 Pod 频繁重启
案例:
- 在一次节点升级过程中,部分 Kubernetes Worker 节点 发生异常,导致 Pod 频繁 Evicted(驱逐),应用服务不可用,最终影响支付和订单创建。
原因分析:
- 节点资源耗尽:某个节点 CPU / 内存超过阈值,导致 K8s 自动驱逐 Pod。
- Pod 无状态设计不完整:部分服务未正确配置 StatefulSet,导致重启后状态丢失。
- 健康检查未优化:Liveness/Readiness 失败后,K8s 反复重启 Pod,未能自动恢复。
紧急补救方案(生产环境应对):
- 手动迁移 Pod:通过
kubectl drain node
迁移受影响的 Pod 到健康节点。 - 临时关闭自动驱逐:修改
kubelet
配置,避免节点压力过高时频繁驱逐。 - 重启异常节点:检查
dmesg
/syslog
日志,确保是 K8s 调度问题,而非硬件故障。
长期解决方案(架构优化):
✅ HPA 自动扩容:结合 CPU / QPS 指标自动扩容,避免单节点超载。
✅ StatefulSet + PV:对有状态服务(如 Redis、TiDB),使用 StatefulSet 持久化存储,确保数据不丢失。
✅ K8s 健康检查优化:合理配置 livenessProbe 和 readinessProbe,避免因短暂抖动导致 Pod 反复重启。
✅ 多可用区部署:跨多个 K8s AZ(可用区) 部署,确保单个节点故障不影响全局可用性。