资讯动态

自研自动容灾系统故障复盘:监控盲区与调优实践

发布时间:2026/10/20 16:13:12 来源:尧图企业网站定制
1. 故障定性一场看起来一切正常的事故先说结论10月这次监控值班表面上是某个免费线路的延迟抖动实际上暴露了我对自研Hermes自动容灾系统过于信任的问题。故障持续了大约47分钟业务方反馈为部分请求偶发变慢而我这边监控面板上所有核心指标——QPS、CPU、内存、成功率——全部平稳只有一条不显眼的HTTP 503率曲线从0.01%悄悄爬到了0.8%随后又回落。这种皮外伤式的曲线最容易麻痹人因为它不够尖锐不够触目惊心。我负责的模拟项目X是一个跨平台在线推理服务依赖两条上游线路一个付费专线和一个免费线路。免费线路平时被我用对了一半流量做成本优化想着有Hermes自动容灾兜底出问题自动切换就行。但这次事故恰恰是自动兜底自己出了问题——它兜住了但兜得很笨更可怕的是我用了将近四十分钟才意识到它已经触发过切换。所以这篇复盘我打算把完整过程写清楚包括故障是怎么发生的、Hermes哪几个机制存在盲区、我做了哪些紧急调优以及事后沉淀下来的一些监控与容灾的经验。内容偏实操适合正在做模型服务监控、自研容灾系统或者只想把手头监控告警做得更皮实的人参考。2. 核心问题拆解为什么线路故障会变成隐形事故2.1 从A线路慢到服务变慢之间隔着一层思维盲区免费线路故障的第一个特征是慢不是挂。免费线路通常不是像断网那样突然不可达而是跨网转发导致延迟抖动。本次故障里免费线路的平均响应时间从正常的120毫秒左右飙到了2200毫秒以上但这个慢先被负载均衡平滑掉了——分摊到整体服务上P99只从180毫秒涨到2400毫秒平均延迟只上升了约15%表面上完全在可接受范围内。第二个特征是偶发。免费线路的不稳定不是持续性的而是周期性的前40秒正常某个调度任务触发了网络竞态紧接着出现1到2秒的高延迟然后恢复。这种脉冲式的抖动用传统的5分钟窗口平均告警几乎测不出来因为聚合之后异常被正常数据稀释了。这里我要给一个非常关键的教训监控指标聚合方式决定了你对故障的感知能力。平均延迟在这个场景下毫无用处因为它掩盖了真实分布。P95、P99能暴露一部分但如果窗口太大也一样被磨平。我用的是1分钟窗口的P99仍然不够敏感——因为故障脉冲只有几秒在60秒窗口里P99被推高了一次但不足以触发我设置的800毫秒告警阈值。2.2 Hermes的自动容灾为什么没有快速解决战斗Hermes是我搭建在服务调用链路上的一层代理服务核心职责是监控每条上游线路的健康状态一旦判定某条线路异常自动把流量切换到其他可用线路。同时支持灰度恢复异常线路恢复后逐渐回切一部分流量验证稳定性。这个设计理念没问题但实现上有一个致命缺陷健康检查探针的采样来源过于单一。当时Hermes的健康检查只依据平均请求延迟和错误率两个维度每10秒采样一次。问题在于当免费线路健康时探针请求本身也会被正常的流量混在一起而正常流量的平均延迟在120毫秒探针本身偶发被调度器卡顿一下就会严重扭曲整体的实时健康判断。我是通过日志发现的Hermes在事故发生后的第3分钟其实已经将免费线路标记为亚健康并触发过一次流量切换。但切换完成之后因为免费线路的延迟恢复正常Hermes在下一个健康检查周期又把它标记为健康于是流量又被切了回去。这就是自动容灾变自动振荡的典型案例。整个振荡周期大约6到8分钟一次期间有一半的请求被送去了时快时慢的免费线路用户感受到的就是服务一会儿正常一会儿又变慢。这种振荡极其危险因为它制造了一种容灾系统在工作的假象实际上却是在掩盖问题延后了真实根因的定位。2.3 为什么说隐形翻车的核心在于缺少真实用户视角另一个我需要自我检讨的地方故障期间监控面板上的成功率是99.6%这个数字太安全了以至于我一开始判断这是个别异常请求不用管。但事后我抽看了业务日志发现慢请求集中在某几个模型输入上——这些输入很大处理时间长触发了上游下载依赖库的逻辑。免费线路慢连带这些请求整体超时而这些请求本身占比不高所以在成功率上只表现为0.4%的掉点但在用户体验层面凡是命中这个路径的用户几乎都会卡很久。这就是我所说的隐形数字上看起来是小问题体验上是完全不可用。我在这次复盘后把监控体系里加了一条新规矩核心服务不仅要监控成功率还要监控慢请求占比并且按输入特征拆分维度而不是只看全局聚合值。故障不可怕可怕的是监控系统把故障磨平了、磨钝了让值班的人看不到真实伤害。3. 从触目惊心到按图索骥监控调优的具体思路3.1 第一步把平均延迟指标拆成多维分位数这是当天我在Hermes里做的第一个修改。删掉了原先针对平均延迟的健康判断逻辑替换为一个滑动窗口内的延迟分位数集合P50反映整体体感P95反映大多数异常场景P99反映极端尾延迟最大延迟用于兜底校验异常高时直接告警。同时把采样间隔从10秒缩短到3秒缩短的意义在于让异常脉冲尽可能少地被窗口稀释。我也调整了判定逻辑只要连续3个采样周期里P99超过800毫秒或者P95超过500毫秒Hermes就开始触发探测模式不再等满一个长窗口。实际做的时候我把这些指标都暴露成了Prometheus指标方便事后回溯。这里给大家一个参考Prometheus的histogram分位数计算在短时间窗口、高基数场景下容易因为桶设计不合理而失真建议把桶的边界设置为50ms、100ms、200ms、500ms、1000ms、2000ms、5000ms这几档太精细反而没有意义。3.2 第二步健康检查从结果判断升级为过程判断我反思了容灾振荡的核心原因健康检查只看上一个周期是否正常而没有判断正常是否稳定。所以我引入了两个新指标延迟波动率当前周期的P99除以前几个周期的P99中位数如果倍率超过2.5即使绝对延迟还没到告警阈值也会触发亚健康连续失败计数上游错误响应超时、连接被重置连续出现N次直接视为不可用不再等延迟指标。这个思路背后是不要把容灾系统做成事后反应而是做成预判反应。提前发现线路开始抖动比等它完全不可用再切换要体面得多。代价是需要面对更多的误判——但误判可以靠第二层确认机制来缓解。我在Hermes里加了一个过渡状态不健康。流量仍然会继续发送一部分过去但比例被限制在20%用于持续验证。只有连续6次采样都表现稳定才恢复权重。这样既不会完全切断也避免振荡。3.3 第三步增加请求染色和链路追踪关联监控的另一个关键是知道问题出在哪一段。原来Hermes做切换我只知道线路B被摘除但不知道哪些用户请求受到影响、影响范围多大。这次我补上了请求染色机制每次请求带上请求头标记当前走了哪条线路、哪个上游如果请求命中亚健康线路就在日志里打点所有信息推送到链路追踪系统方便按traceId查整条链路的耗时分布。这样做的直接收益是故障复盘不再需要猜而是直接按traceId搜几秒钟就能看到这个请求卡在了上游回包阶段。对于个人开发者或者小团队不需要一步到位上完整链路追踪体系哪怕只是在网关层打一条包含线路标识的访问日志就能极大提升容灾排障效率。我建议至少做到请求可追溯、线路可区分、状态可查询这三件事。4. 紧急调优过程记录Hermes自动容灾的调整实操4.1 调整一健康检查频率与熔断阈值的联动原先Hermes的配置里熔断触发条件是连续3次检查失败。这个数字在十分钟窗口内没问题但在秒级抖动场景下太迟钝了。我把配置改成了动态阈值模式当线路处于健康状态时连续2次延迟异常即可触发探测当线路处于探测状态时只要有一次错误响应立即摘除流量当线路处于恢复状态时需要连续6次采样正常且无错误才允许重新把权重调回100%。这段逻辑我直接在Hermes的配置中心改不用重启服务。核心代码如下大家可以参考。# Hermes容灾策略配置片段 health_check: interval: 3s timeout: 1500ms success_threshold: 6 failure_threshold: 2 degraded_threshold: 1 weight_control: max_healthy_weight: 100 min_probe_weight: 20 recovery_step: 20 recovery_interval: 2m这里有个计算逻辑我当时手推了一遍免费线路恢复后从20%权重恢复到100%每2分钟上调20%需要约8分钟。为什么不是直接切回100%因为恢复本身也可能是一次假象尤其是在免费线路这种外部依赖上。慢热回切给了系统纠错的机会。4.2 调整二把免费线路降级为半信任线路既然是免费线路稳定性和服务质量本身就不受我们控制那我一开始就不该给它配50%的流量权重。这是战略层面的失误。调整后我把默认权重这样分配线路类型原权重调整后权重触发摘除的阈值付费专线50%70%P99 800ms连续3次免费线路50%30%P99 500ms连续2次核心思想是信任度越低的线路越敏感地摘除且初始分配流量越少。这个原则跟技术关系不大但跟系统稳定性关系极大。免费线路不是不能用而是要用在锦上添花的位置而不是中流砥柱。另外我还给免费线路单独设置了识别标记所有走这个线路的请求都会带上一个特定的Header标记便于追溯。如果业务方对延迟敏感度极高甚至可以在请求级别做选择核心高优请求强制走付费专线普通低优请求才允许调度到免费线路。4.3 调整三为Hermes增加半开恢复与自动回归逻辑发生振荡的根本原因是恢复逻辑太脆。我重新梳理了恢复状态机HEALTHY - PROBING - DEGRADED - UNHEALTHY - RECOVERING - HEALTHY关键一点是从任意非健康状态返回HEALTHY必须经过RECOVERING并且RECOVERING期间持续观察线上真实指标而不是只看探针结果。这个状态机不复杂但它是这次调优里最值得写下来的一段。很多容灾系统的切换做得很激进恢复做得很草率最后形成一个反复切开又反复接回的坏循环。半开恢复的核心收益是给上游线路一个再证明确实稳定的时间窗口。我的实现里RECOVERING使用了一个时间窗口计数器每次通过一次健康检查就1不通过直接清零回到DEGRADED。这是从断路器的半开状态借鉴过来的思路但做了一层更细的梯度恢复每增加一个健康计数权重就增加一点直到连续6次完全健康才回归满权重。5. 故障复盘中最容易被忽视的三个监控盲区5.1 盲区一只看平均值不看分布和长尾这是老生常谈但我还是要用这次事故的教训再强调一遍平均延迟从120ms涨到140ms你根本察觉不到问题但P99可能已经翻了十倍。尤其是模型服务这种调用链复杂的场景一次上游抖动就足以让一小部分请求彻底超时而这部分请求占比不高平均下来就被稀释了。我的建议是每个核心接口必须同时展示三项指标平均耗时、P95耗时、P99耗时。一旦P99超过P95的3倍就说明存在明显的长尾异常值得排查。5.2 盲区二依赖健康的检测请求和真实业务流量混在一起那次故障里Hermes的健康检查探针有一部分是直接复用真实业务请求的采样结果。这个设计省事但极容易出偏差——因为真实业务请求的内容大小、网络路径、处理逻辑千差万别一个超大输入导致的慢请求会被误判为线路问题。正确做法是把探针拆开专门用小体量、低超时上限的探测请求只测链路的连通性和基本延迟不处理复杂业务逻辑。如果探针延迟都很高再判定线路异常。这个改动很细小却直接影响容灾系统是否误触发。5.3 盲区三没有真正模拟故障产生的影响面我后来补做了一次故障演练模拟免费线路全挂的场景观察Hermes是否能在15秒内完成切换以及切换过程中有多少请求超时。结果发现一个有趣的现象切换本身很快但切换后由于每条上游的连接池是独立的新线路的连接建立需要握手导致前30秒内一批新请求延迟偏高。这个盲区不在监控里在容量规划里。我把连接池预热的逻辑改成了常驻保活确保备用线路时刻有可用连接。这一条如果不是真的演练靠看监控曲线根本发现不了。6. 监控指标清单与告警规则参考6.1 Hermes核心监控指标我整理了一份当前Hermes暴露的核心指标供参考指标名称类型说明告警建议hermes_upstream_health_statusgauge上游线路健康状态0/1/2/3状态不等于0时告警hermes_upstream_request_latency_p99histogram每条上游线路的P99延迟P99 800ms持续3次告警hermes_upstream_error_rategauge上游错误率连续2次超过2%告警hermes_weight_adjust_totalcounter权重调整次数3分钟内超过4次触发注意hermes_circuit_breaker_stategauge熔断器状态状态跳变时通知值班6.2 一套比较稳的告警组合我不会只依赖单一指标触发告警而是组合判断错误率超过2%且P99超过800ms触发P1告警P99超过800ms但错误率正常触发P2告警进入观察权重调整次数异常增多触发P2告警重点排查振荡任何线路的连续健康探针失败超过6次直接触发上游不可用告警。这套组合可以在过于灵敏的误报和过于迟钝的漏报之间取得一个平衡。具体阈值因业务而异但组合思路是通用的。7. 这份经验对后续架构设计的意义这次调优虽然起因是一个免费线路的故障但暴露出的问题在自有基础设施里同样存在——任何依赖外部组件、外部服务的系统都需要重新审视容灾策略的感知精度和恢复策略。我个人总结下来有三点后续可以持续扩展第一将Hermes的容灾能力从线路级扩展到模型级。不同模型的调用特征差别很大有的模型对延迟极度敏感有的模型对错误率极度敏感。线路级判断无法覆盖这种差异必须建立更细力度的策略矩阵。第二把演练从应急动作变成周期性动作。这次故障让我意识到没有故障演练过的容灾等于没有容灾。我计划每个月做一次免费线路全挂模拟验证切换耗时、恢复节奏和告警链路是否仍然有效。容灾系统最怕的不是故障而是长期不用导致逻辑锈死。第三将监控告警的能力输出为经验库。每次故障后把异常特征、排查路径、应对方法沉淀成条目下次再出现类似曲线波动直接匹配经验库能大大缩短定位时间。我们现在已经在用模拟话术整理这些经验同类故障的平均定位时间已经从30分钟压到了5分钟以内。8. 写在最后的一点实操体会经历了这次隐性翻车我最大的体会是做监控和容灾不能只关注指标是否被触发系统是否切换了更要关注故障发生时人的感知速度是否足够快。Hermes的自动切换原本是为了减少人工干预但如果切换动作缺乏可感知、可追溯的痕迹反而会让工程师失去对系统的掌控感。我后来给Hermes加了一个动作记录频道每次发生切换、摘除、恢复动作都会自动生成一条结构化事件消息推送到值班群。这样哪怕不在系统旁边也能第一时间知道容灾系统做了什么。这条改动成本极低但对运维感知的提升非常明显。还有一个小技巧值得分享调优容灾参数时千万不要一次性把所有阈值改到位而是每次只改一个变量观察一段时间。同时调整多个参数只会让故障复盘变成一锅粥很难判断是哪一项改动起了作用。我自己这次就靠一次只改一个的节奏才比较快地锁定了问题所在。把这个经验沉淀下来后面不管是做模型服务还是其他在线系统这套容器监控自动容灾快速感知的三角组合都会是值得反复打磨的核心能力。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑