第25章:生产环境运维:灰度发布策略,容量规划,灾备方案(主备/多活),SLA保障
做市商系统上线了,代码写完了,回测也漂亮。然后呢?
真正的考验才刚刚开始。我见过太多团队,系统在开发环境跑得飞起,一上生产就各种翻车。说白了,运维不是擦屁股,而是系统设计的一部分。这一章,我就把生产环境运维的几个核心话题掰开揉碎讲清楚。
核心观点:做市商系统的运维,本质是管理「风险」—— 代码变更的风险、流量洪峰的风险、硬件故障的风险。灰度、容量、灾备、SLA,都是围绕风险展开的。
25.1 灰度发布策略:别让新代码炸掉整个盘口
做市商系统最怕什么?最怕新版本上线,一个bug导致所有订单都发错价格。我当年在XX交易所就遇到过,一次全量发布,策略里一个除零错误没处理,直接导致所有做市商机器同时报错,盘口瞬间塌了。嗯,那天的复盘会开了整整8个小时。
所以,灰度发布不是可选项,是必选项。我的习惯是分三层灰度:
- 第一层:内部灰度(1%流量)。只让内部测试账号或者模拟盘跑新版本。观察日志、延迟、成交率。这层通常跑1-2小时。
- 第二层:低风险灰度(5%-10%流量)。选择一些交易量小、波动率低的品种上线新版本。比如某些冷门永续合约。这层跑4-8小时,覆盖一个完整的交易时段。
- 第三层:全量发布(100%流量)。确认无误后,逐步切到所有品种。注意是「逐步」,不是一键切换。我一般分3-5批,每批间隔5分钟。
这里有个关键点:灰度发布必须支持「一键回滚」。我曾经吃过亏,灰度到一半发现内存泄漏,结果回滚脚本没写好,花了20分钟才恢复。20分钟,对于做市商系统来说,足够亏掉一个月的利润了。
我的经验:灰度发布和回滚脚本,一定要在预发布环境演练至少3次。别等到真出事了再试。另外,灰度期间要盯紧「订单拒绝率」和「成交延迟」这两个指标,它们比CPU、内存更敏感。
25.2 容量规划:你的系统能扛住「双十一」吗?
做市商系统的流量不是均匀的。平时可能每秒几百笔订单,但遇到行情剧烈波动,比如某个币种突然暴跌,瞬间可能涌来几万笔撤单和改单。你的系统能扛住吗?
容量规划,说白了就是回答三个问题:
- 当前系统能处理多少TPS?
- 峰值流量是多少?
- 瓶颈在哪里?
我习惯用「压测 + 监控 + 预估」的组合拳。
首先,压测不能只在实验室做。我建议在预发布环境,用生产流量的回放工具(比如GoReplay或自研的流量录制工具)进行压测。这样压出来的数据才真实。我记得有一次压测发现,数据库连接池在500 TPS时就打满了,但代码里配置的是1000。查了半天,原来是连接池的「最大等待时间」设得太短,导致连接被频繁回收。这种坑,不压测根本发现不了。
其次,容量规划要留余量。我的经验是:线上实际使用量不超过理论峰值的60%。比如压测显示系统能扛2000 TPS,那线上日常流量控制在1200 TPS以内。为什么?因为行情波动时,流量可能瞬间翻倍,你得给系统留出喘气的空间。
最后,容量规划不是一次性的。每季度至少做一次全面压测,每次大版本发布前也要做。做市商系统的流量增长很快,今天够用,下个月可能就不够了。
避坑指南:我曾经遇到过一个案例,压测时一切正常,但上线后一到凌晨3点就卡顿。查了三天才发现,是数据库的定时备份任务和交易高峰撞车了。所以,容量规划一定要考虑「后台任务」对系统资源的抢占。
25.3 灾备方案:主备 vs 多活,怎么选?
做市商系统是7x24小时运行的。一旦宕机,每一秒都是真金白银的损失。灾备方案,我把它分为三个等级:
| 等级 | 方案 | RTO(恢复时间目标) | RPO(数据恢复点目标) | 适用场景 |
|---|---|---|---|---|
| L1 | 冷备 | 小时级 | 分钟级 | 非核心模块,如历史数据查询 |
| L2 | 主备(Active-Standby) | 分钟级 | 秒级 | 核心交易引擎,但预算有限 |
| L3 | 多活(Active-Active) | 秒级 | 零丢失 | 头部做市商,对延迟和可用性要求极高 |
我个人最推荐的是「同城双活 + 异地灾备」的组合。什么意思呢?
- 同城两个机房,同时提供服务。一个挂了,另一个秒级接管。延迟差异控制在1毫秒以内。
- 异地一个机房,作为冷备或温备。主要防「同城双活」同时挂掉(比如地震、火灾)。异地机房的RTO可以放宽到15分钟。
这里有个技术难点:多活架构下的数据一致性。做市商系统的订单状态、持仓数据、资金余额,都是强一致性的。两个机房同时写,怎么保证不冲突?我的方案是「按品种分片」。比如BTC/USDT这个交易对,只在一个机房处理;ETH/USDT在另一个机房。这样避免了跨机房的分布式事务。如果非要跨机房处理,那就用「最终一致性」+「冲突检测」的模型,但复杂度会高很多。
我的建议:对于大多数做市商团队,主备方案已经够用了。多活的收益和成本不成正比。除非你的日均交易量超过10亿美元,否则别碰多活。把精力花在「快速切换」和「数据校验」上,性价比更高。
25.4 SLA保障:把承诺变成可量化的指标
SLA(服务等级协议)不是写给客户看的,是写给自己看的。它定义了「什么算正常,什么算故障」。我见过最糟糕的SLA是「系统可用性99.9%」,但连「可用性」怎么算都没说清楚。
做市商系统的SLA,我建议至少包含以下指标:
- 可用性(Uptime):月度可用性 ≥ 99.99%。注意,这里要排除计划内维护窗口。我习惯把维护窗口定在每周三凌晨2:00-4:00,提前24小时公告。
- 延迟(Latency):订单处理延迟 P99 ≤ 10毫秒。超过50毫秒算一次「慢查询」,需要记录和复盘。
- 错误率(Error Rate):订单拒绝率 ≤ 0.1%。注意,拒绝率不等于错误率。有些拒绝是策略主动控制的(比如风控拦截),不算故障。
- 数据一致性:订单状态、持仓、资金余额的最终一致性延迟 ≤ 5秒。超过30秒算数据不一致事件。
有了SLA,还要有监控和告警。我的原则是:告警不是越多越好,而是越准越好。我曾经接手过一个系统,每天告警上千条,运维人员直接麻木了。后来我把告警规则砍掉了80%,只保留那些「需要人工介入」的告警。比如:
- 延迟P99连续5分钟超过20毫秒 → 告警
- 订单拒绝率连续3分钟超过1% → 告警
- 数据库连接池使用率超过80% → 告警
- CPU使用率超过90% → 只记录日志,不告警(因为CPU高不一定是故障)
一个小技巧:告警一定要带上「处理建议」。比如「数据库连接池使用率超过80%,建议检查慢查询或扩容连接数」。这样值班人员不用翻文档就能快速响应。
25.5 知识体系总览
下面这张图,是我对本章知识体系的总结。你可以把它当作运维工作的「检查清单」。
这张图把灰度、容量、灾备、SLA串在了一起。你会发现,它们不是孤立的。比如,灰度发布的结果会影响容量规划(新版本性能变差了?),灾备方案决定了SLA中的RTO和RPO。运维是一个系统工程,牵一发而动全身。
好了,这一章的内容就到这里。生产环境运维没有银弹,只有持续地压测、监控、复盘、优化。记住一句话:没有经历过生产环境毒打的系统,不算真正的做市商系统。