服務熔斷這個坑,我們填了三次
上週給一家客戶的內部問答系統做交付,最狼狽的不是模型答錯,而是熔斷器把整個服務切崩了。三次。三次都是同一個設定,三次都怪我沒想到。

服務熔斷這個坑,我們填了三次
上週給一家客戶的內部問答系統做交付,最狼狽的不是模型答錯,而是熔斷器把整個服務切崩了。三次。三次都是同一個設定,三次都怪我沒想到。
事情是這樣的:客戶的問答走我們的一層代理,代理後面接大模型 API,超時設 30 秒,錯誤率超過 30% 就熔斷,熔斷後直接返回兜底文案。聽起來挺穩,對吧?
第一次翻車:模型有一次生成慢,35 秒才出結果,代理記成超時。連續幾個慢請求把錯誤率推過閾值,熔斷觸發,後面所有問題都返回「服務暫時不可用」。其實模型只是慢,不是掛了。
第二次翻車是修完超時之後。我們把超時放寬到 90 秒,結果熔斷半開時只放行一個試探請求,這個請求又碰上慢生成,再次失敗,又回到熔斷。半開狀態變成了一個放大器:它不生產錯誤,但會把一個偶發慢請求放大成全域故障。
第三次最隱蔽。我們改了策略:半開時放行三個試探請求。上線當天流量正好低,三個請求全成功,熔斷「恢復」了。可真實問題是間歇性的——恢復後流量上來,問題復現,又熔斷。客戶那邊看到的是服務正常了又抽風,比一直報障更讓他們沒安全感。
最後真正修好,靠的不是把熔斷參數調得更精巧,而是拆掉了一層偽需求:客服場景根本不需要硬熔斷。我們改成三件事:
一是把超時和熔斷解耦。慢請求不再計入錯誤率,單獨進一個限流佇列,超過佇列長度才排隊拒絕,返回「稍後重試」而不是「服務不可用」。客戶能分辨「排隊」和「故障」,這兩個詞對信任的影響完全不同。
二是熔斷只保護真正的依賴故障:連線拒絕、5xx、閘道器錯誤。生成慢不算。這個改完之後,熔斷從一週觸發八次變成兩個月沒觸發過。
三是加了熔斷狀態可見性。後台能看到當前是關閉、打開還是半開,半開時放行幾個、成功幾個。有了這個,第三次那種「看著好了其實沒好」的故障,我們當天就定位了,不用等客戶投訴。
這裡多說一個容易被忽略的點:兜底文案本身也是設計的一部分。我們原來的兜底是「服務暫時不可用,請稍後再試」,改完之後分成了兩種:排隊場景返回「當前諮詢較多,約 1 分鐘後回覆你」,真正故障才返回「服務異常,我們已收到告警」。上線後客戶投訴裡「你們是不是掛了」這種問句明顯變少了。文字不是裝飾,它是故障時刻的最後一道防線:使用者失去回答的時候,接住他們的是這段話,不是模型。
復盤下來,我的體會是:熔斷是個好的保護機制,但它保護的是依賴,不是業務。把「業務上的一次延遲」交給熔斷去裁決,它就會在你最沒防備的時候把整個入口關死。交付現場判斷一個保護機制設計得好不好,就看一條:故障時使用者看到的是「我在排隊」還是「你們掛了」。前者留得住人,後者留不住。
留言區
歡迎分享你的想法!
載入留言中…