一、库存系统高可用概述
什么是高可用
高可用,说白了就是系统能不间断地提供服务。
我见过不少刚入行的朋友,一听到「高可用」就想到集群、想到负载均衡。其实没那么复杂。你想想看,一个系统如果动不动就挂掉,用户点个下单按钮转圈五分钟,那还谈什么可用性?
我个人习惯把高可用拆成两个维度来看:
- 不出错 —— 系统能稳定运行,不崩溃、不超时
- 出错了能快速恢复 —— 哪怕挂了,也能在几秒内自动拉起来
嗯,这里要注意,高可用不是「永远不挂」,而是「挂了之后用户几乎感知不到」。
核心公式:
可用性 = 正常运行时间 / (正常运行时间 + 故障时间)
业界常用「几个9」来衡量:99.9%(三个9)意味着每年宕机不超过8.76小时,99.99%(四个9)则是不超过52.56分钟。
库存系统的核心挑战
库存系统为什么难做?我直接说结论:因为它是「状态敏感」的系统。
我在项目中遇到过好几次这样的场景:双十一大促,流量瞬间冲上来,库存扣减接口被疯狂调用。这时候如果系统挂了,后果是什么?超卖、少卖、订单无法履约……每一个都是灾难。
具体来说,库存系统面临这几个核心挑战:
- 并发扣减 —— 同一件商品,成千上万人同时下单,库存怎么扣才不超?
- 数据一致性 —— 库存扣了,但订单没生成;或者订单生成了,库存没扣。这种「对不上」的情况怎么处理?
- 性能与可用性的平衡 —— 为了保证数据准确,加锁加得死死的,结果系统响应慢得像蜗牛。用户等不了,系统也扛不住。
- 外部依赖的脆弱性 —— 库存系统往往要依赖数据库、缓存、消息队列。任何一个环节出问题,都可能引发连锁反应。
避坑提醒: 我曾经接手过一个库存系统,上线前压测一切正常,结果大促当天数据库连接池被打满,所有请求排队等待,最终导致服务雪崩。后来排查发现,问题出在「每个请求都开了独立事务,且没有设置超时时间」。
所以,连接池、超时时间、熔断降级,这三样东西在库存系统里一个都不能少。
高可用设计目标与衡量指标
做高可用设计,不能拍脑袋。你得有明确的目标,还得有可量化的指标。
我个人习惯把目标分成三层:
| 层级 | 目标 | 说明 |
|---|---|---|
| 第一层 | 服务不中断 | 系统在任何情况下都能正常处理请求 |
| 第二层 | 数据不丢失 | 库存数据不能丢,哪怕机器宕机 |
| 第三层 | 快速恢复 | 出问题后,能在秒级或分钟级恢复 |
衡量指标方面,我建议重点关注这几个:
- 可用性百分比(SLA) —— 前面提到的「几个9」,这是最直观的指标
- 平均故障间隔时间(MTBF) —— 系统平均多久出一次故障,越长越好
- 平均恢复时间(MTTR) —— 出故障后多久能恢复,越短越好
- 请求成功率 —— 比如99.9%的库存扣减请求都能成功返回
- 数据一致性延迟 —— 库存扣减后,多久能在所有节点看到最新数据
我的经验: 别一上来就追求四个9。对于大多数业务场景,三个9(99.9%)已经够用。盲目追求高可用,成本会成倍增加。先搞清楚业务容忍度,再定目标。
库存系统高可用架构全景图
下面这张图,是我梳理的库存系统高可用架构的核心逻辑。你可以把它当作本章的知识地图:
这张图其实就讲了一件事:高可用不是某一个环节的事,而是从接入层到数据层的全链路设计。每一层都有自己要解决的问题,每一层也都有对应的容错手段。
举个例子,接入层的限流和熔断,是为了防止流量把后端冲垮。缓存层是为了扛住高并发读,减轻数据库压力。数据层的主从复制和分库分表,则是为了在数据库层面做到高可用。
嗯,这里要特别强调一点:别指望一层解决所有问题。我见过有人把全部希望寄托在Redis上,结果Redis一挂,整个库存系统直接瘫痪。正确的做法是每层都做冗余,每层都做降级方案。
一句话总结本章:
高可用不是玄学,它是「设计出来的」。从目标设定到指标衡量,从架构分层到容错策略,每一步都要想清楚。库存系统尤其如此,因为它的每一次故障,都可能直接导致真金白银的损失。