五年磨一劍:滴滴順風車服務端之穩定性規範

點擊上方“zhisheng”,選擇“設爲星標”

後臺回覆"666",獲取新資料

桔妹導讀:本文給出其中穩定性相關的規範,這些規範都是順風車成立五年來,對大量真實線上故障覆盤、總結得到的,希望對大家服務的穩定性提升有所幫助。

本文轉自:滴滴技術

服務端作爲順風車技術部內最大的工程團隊,隨着人員的擴張和迭代,流程規範在其中扮演着原來越重要的角色。一方面規範化可以提高我們的交付質量、交付效率,另一方面,我們也希望在一次次的實戰中不斷的總結,探索出適用於我們團隊的最佳實踐。

基於此,我們制定並推廣了一套適用於服務端開發的可執行、最小限制的工程規範,包括研發流程、穩定性、性能成本等多個方面。

本文給出其中穩定性相關的規範,這些規範都是順風車成立五年來,對大量真實線上故障覆盤、總結得到的,希望對大家服務的穩定性提升有所幫助。

1

名詞解釋

下文的描述中,會用到很多的技術名詞,爲更容易的理解,在這裏對這些名詞做下簡要說明:

  • 服務分級: 

    根據業務需要,一般的我們需要針對最小系統劃分爲一級服務,一旦出問題需要第一優先級跟進。我們將影響業務核心指標(比如發單量、成單量等)的服務定義爲一級服務,其他爲二級服務。

  • 預覽集羣: 和線上生產環境的部署完全一致的一套環境,只是無線上流量,可以內部訪問,集羣內流量閉環。

  • 小流量集羣: 和線上生產環境的部署完全一致的一套環境,通過流量控制,只有個別城市的流量會落到此集羣,集羣內流量閉環。

  • 灰度發佈: 將發佈過程分爲預覽集羣、灰度城市集羣、10%流量、50%流量、100%流量的發佈機制,確保安全上線過程。

  • 全鏈路壓測: 在不影響線上服務的前提下,對生產環境進行壓力測試的解決方案。用以摸清生產環境的容量、瓶頸點等。

  • 機房多活: 通過多機房部署,當一個機房出現故障時,可以快速將流量切到其他機房,以減少損失。涉及流量路由、流量閉環、數據同步、數據一致性、災難應對等諸多環節的整套解決方案。

2. 

穩定性規範

穩定性設計

  • 【強制】調用方必須設置超時時間,且調用鏈路超時從上往下遞減,建議超時時間設置如下:

  • 【強制】核心流程新增依賴默認爲弱依賴,如需新增強依賴,需要經過評審決議;

  • 【強制】下游服務如提供服務發現,所有服務必須通過服務發現訪問該服務,方便服務發現控制下游節點和超時時間;

  • 【強制】所有內部服務必須接入服務發現,外部服務儘量推動接入服務發現;

  • 【建議】建議框架支持依賴服務手動一鍵熔斷;

  • 【建議】服務設計優先考慮無狀態設計;

  • 【建議】寫接口建議考慮防重入;

  • 【建議】系統設計原則簡單可靠,優先使用成熟技術;

  • 【建議】核心服務強制,其他建議,接口建議設置合理的限流配置。

部署和運維

  1. 【強制】嚴禁在臨時腳本中未通過接口或封裝方法,直接操作線上數據,如有需要,必須經過QA測試;

  2. 【強制】服務上線必須通過上線平臺,並接入質量平臺(功能包括自動化case、核心曲線圖及其他上線checklist),強制停留觀察’

  3. 【強制】一級服務需要包含預覽集羣、小流量集羣(除部分特殊服務)並且雙機房部署;

  4. 【建議】非一級線上服務建議包含預覽集羣;

  5. 【建議】新服務上線建議進行容量規劃,建議通過接口壓測或全流量壓測驗證模塊容量。

監控告警

  1. 【強制】線上服務機器必須有基礎監控報警,包含CPU、IO、內存、磁盤、coredump、端口;

  2. 【強制】線上服務必須有基礎的服務監控,包括接口qps、fatal數量、耗時;

  3. 【建議】核心業務指標(發單量、搶單量、支付量等)必須有監控和報警;

  4. 【建議】需要有服務整體大盤,能夠涵蓋該方向核心模塊監控,方便快速定位服務問題。

變更管理

  1. 【強制】任何一級服務變更,均需要走灰度發佈機制;

  2. 【強制】任何一級服務變更,包括服務變更、配置變更,均需要有相應的回滾預案,保證變更異常時可以快速回退;

  3. 【建議】儘量避免代碼搭車上線;

  4. 【建議】服務回滾時建議同時回滾相應的代碼和配置,保證主線代碼的正確性;

  5. 【建議】配置變更,特別是複雜的配置變更時,建議增加相應的配置校驗機制。

預案管理

  1. 【強制】必須有多活切流預案,且需要保障有效性,必須定期組織演練,建議1月1次;

  2. 【強制】全鏈路壓測通道需要保證有效性,定期組織壓測;

  3. 【強制】一鍵限流預案需要保障有效性,定期review和演練;

  4. 【強制】強依賴降級預案需要保障有效性,定期演練。

故障處理原則

  1. 【強制】線上出現故障時,必須第一優先級進行處理;

  2. 【強制】線上出現故障時,如果有變更,第一時間回滾;

  3. 【強制】線上出現故障,必須組織覆盤;

  4. 【強制】需要有覆盤規範,覆盤按照規範執行。

3. 

穩定性反模式

本章節主要是基於大量的線上故障case,以具體實例驅動,加上研發全流程中各個環節容易犯的一些穩定性問題,提取一些反模式出來,供大家參考,儘量避免後續的工作中犯同樣的問題,提高線上服務的穩定性。

3.1.容災和容錯設計

反模式3.1.1 

過度的節點熔斷策略

【實例】

爲了提高請求成功率,在下游故障時對下游節點採取熔斷措施,比如1分鐘內連續出現5次訪問出錯,則將該節點熔斷,不再調用(過一段時間後再恢復),某天網絡抖動,下游服務4個實例中的3個均進入熔斷模式,導致訪問下游的所有流量均落到剩餘的這個實例上,壓力過大,將該實例壓垮。下游服務雪崩,整個系統不可用。

【解決方案】

熔斷模式下,還需要有熔斷保護措施,避免過度熔斷帶來的穩定性問題。

反模式3.1.2 

固定的重試序列

【實例】

每次重試序列都爲“下一臺”。

【後果】

一個是雪崩:假設某一類 query 的重試序列爲A B,當 A 出現故障時,B 要承受兩倍的壓力,如果 B 扛不住,那麼 B 的下一個也會被壓垮;一個是上線損失流量:假設重試次數是2,上線時如果 A 和 B 同時重啓,那麼重試序列爲 A B的 query 必然無結果。

【解決方案】

評估新的重試算法,比如隨機重試。不過相對於固定的重試序列,隨機重試序列也可能給系統帶來風險,例如可能會降低下游模塊的cache命中率,降低系統性能。

反模式3.1.3 

不合理的超時設置

【實例】

上游服務超時時間設置不合理,下游出現問題時,直接把上游服務拖垮。

【解決方案】

應該根據鏈路的99分位耗時來設置超時時間,同時定期對鏈路的通信相關配置進行review。

反模式3.1.4 

未考慮同一請求中多次調用下游的影響

【實例】

服務調用下游時超時時間設置沒有問題,但同一請求中會串行多次調用某個下游服務,下游服務故障時,也會把上游服務直接拖垮。

【解決方案】

除了考慮對下游服務的單次超時,還需要考慮對下游服務的總體超時。

反模式3.1.5 

不合理的重試邏輯

【實例】

整條鏈路多個地方有重試,下游服務故障時,重試被放大,導致服務雪崩。

【解決方案】

評估重試機制,梳理請求處理的整個鏈路,保證重試收斂在一個地方。

反模式3.1.6 

沒有考慮到業務毛刺的影響

【實例】

某業務形態有個特點,在半點和整點時刻有請求尖刺,某次受節假日影響,訪問下游的流量瞬間暴增,導致下游服務雪崩。

【解決方案】

對業務尖刺進行平衡處理,減少對下游服務的峯值流量衝擊。

反模式3.1.7 

沒有對異常輸入進行容錯處理

【實例】

業務沒有對異常輸入進行容錯處理,仍然按照正常邏輯處理,導致數據混亂。

【解決方案】

業務特別是業務入口,必須對不合理的異常輸入進行容錯處理,保證整個系統的健壯性。

反模式3.1.8 

接口不支持冪等性設計

【實例】

接口不支持冪等性,網絡故障時引發大量的重試,導致核心數據大量出錯。

【解決方案】

接口設計的時候就需要考慮冪等性的需求。

反模式3.1.9 

沒有對非核心流程弱依賴化

【實例】

沒有對流程進行弱依賴化,導致系統整體上比較脆弱,每個依賴單元故障都會導致整個業務癱瘓。

【解決方案】

定期對系統的流程進行梳理,最小系統化,非必須流程儘量弱依賴化。

反模式3.1.10 

沒有考慮ID溢出的影響

【實例】

某ID使用int32,超出後ID溢出,導出服務異常。

【解決方案】

增加資源相關的ID字段時要考慮ID的範圍,是否有溢出風險

定期對資源相關的ID字段進行review,提前預防,最大限度防止故障的發生

3.2.部署和運維

反模式3.2.1 

部署時未考慮網段因素

【實例】

服務部署時未考慮網段因素,服務的多個實例都部署到一個交換機下,導致交換機故障時,服務的多個實例不可用,服務所在集羣雪崩

【解決方案】

服務部署時儘量多考慮地理因素,同一服務的多個實例儘可能部署到不同的機房、交換機和網段下

反模式3.2.2 

服務混部時未做好資源隔離

【實例】

多個服務混部,其中一個CPU佔用過高,導致其他服務異常

【解決方案】

多個服務混部的情況下,一定要做好資源隔離,避免因一個服務佔用資源過高,導致同一臺機器上的其他服務不可用

反模式3.2.3 

沒有做到對核心業務和隔離和保護

【實例】

某非核心流程由於bug向mq寫入大量消息,導致整個mq集羣不可用,整個業務故障

【解決方案】

核心鏈路和非核心鏈路的mq隔離,分開部署,非核心流程的變化不會影響主流程,保證核心流程和業務的穩定性

3.3.容量管理

反模式3.3.1 

容量規劃時未考慮故障因素

【實例】

線上某服務qps不大,只部署了2個實例,一個實例高峯期出問題時,流量都落到另外一個實例上面,把服務壓垮

【解決方案】

容量估計時需要考慮容災因素,預留一定的buffer

如果覺得部署實例多,會浪費機器,可以考慮使用彈性雲,比較靈活

反模式3.3.2 

上線新功能未合理進行容量規劃

【實例】

某服務,下游依賴衆多,在進行容量規劃時,重點都集中在某一依賴服務,未對全局所有依賴方進行全面評估,當其中某一依賴服務出現問題,導致整體服務不可用

【解決方案】

上線新功能時,需要對所有下游依賴服務進行容量規劃,防止出現瓶頸點

3.4.變更管理

反模式3.4.1 

代碼搭車上線

【實例】

由於缺乏有效的代碼修改管理機制,某產品線由於代碼搭車上線,出現過多次線上故障

並且由於變更時涉及的修改比較多,導致問題定位和追查時非常困難

【解決方案】

建立嚴格的代碼管理機制,嚴禁代碼搭車上線,保證任何時刻主幹沒有未上線驗證的代碼

反模式3.4.2 

服務回滾時遺漏回滾代碼

【實例】

上線出現問題,服務回滾後沒有第一時間把代碼回滾掉。第二天其他同學上線時將未回滾的問題代碼再次帶上線,上線時導致連續兩天出現系統故障

【解決方案】

服務回滾的時候同時第一時間回滾代碼

反模式3.4.3 

過高的併發部署設置

【實例】

部署配置的併發個數太高,導致同一時刻只有少數機器可用,引發集羣雪崩

【解決方案】

服務部署配置的併發個數,要保證剩餘機器能夠承載業務全部流量

反模式3.4.4 

服務啓動或回滾時間過長

【實例】

服務上線異常,回滾時單個服務回滾時間太長,導致未能短時間內快速止損

【解決方案】

定期檢查服務的啓動和回滾時間,保證出現故障時可以第一時間完成回滾操作

反模式3.4.5 

配置文件缺少有效的校驗機制

【實例】

配置文件由模型產出,數據配送系統實時配送到線上服務,模型產生的配置文件有問題,引發線上故障

【解決方案】

針對配置文件,尤其是模型產出的配置文件,建立嚴格的檢查和校驗機制

反模式3.4.6 

配置變更沒有灰度

【實例】

配置相關修改,穩定性意識上重視度不夠,沒有進行足夠的觀察和灰度,導致故障

【解決方案】

所有變更,包括服務變更、配置變更、數據變更以及環境變更,都需要進行嚴格的觀察和灰度,保證變更的質量

反模式3.4.7 

變更沒有經過嚴格的測試

【實例】

變更較小,感覺沒有必要進行測試,結果出現低級錯誤,導致故障

【解決方案】

任何變更都要測試、double check,修改一行代碼,也可能導致線上的穩定性故障

反模式3.4.8 

變更時沒有嚴格按照變更規範執行

【實例】

上線時,小流量和A機房均嚴格按照規範檢查,服務和各種曲線沒有問題,上線B機房時沒有進行檢查。結果B機房出現故障。

經排查是因爲B機房配置缺失

【解決方案】

任何變更都要嚴格按照變更規範嚴格檢查,上線的每個階段都要檢查服務的各種曲線和指標

反模式3.4.9 

離線直接通過sql更新db數據

【實例】

直接通過sql進行離線更新數據庫,沒有做好限流保護,導致db壓力大,線上服務訪問時出現大量超時

【解決方案】

  • 除非特殊情況,嚴禁直接通過sql操作db數據,修改需通過接口修改,方便通過曲線觀察,也可降低直接改庫的風險;

  • 批量修改db數據需要通報dba,經過review,確認沒有問題時纔可以進行操作;

  • 批量增改、增加數據務必做好限流措施。

3.5.監控報警

反模式3.5.1 

缺少基礎監控

【實例】

缺少基礎監控,導致出現故障,未能第一時間感知。

【解決方案】

梳理基礎監控checklist,定期對服務的基礎監控進行review和演練。

反模式3.5.2 

缺少業務監控

【實例】

缺少業務監控,導致出現故障,未能第一時間感知。

【解決方案】

對核心流程和核心業務指標,都需要添加業務監控。

反模式3.5.3 

告警閾值設置有問題

【實例】

由於業務bug導致線上大量告警,先臨時將告警閾值從20調整到200,問題修復上線後忘了改回來,就一直維持這個閾值設置,導致後續業務出問題的時候,未能第一時間報出來。

【解決方案】

儘量使用短暫屏蔽報警,而不是調高閾值。

反模式3.5.4 

監控告警當前已失效

【實例】

業務迭代過快,導致監控告警信息和業務已經不再匹配。

【解決方案】

  • 定期對告警進行演練,保證其有效性。

  • 重大業務迭代,需要將監控告警列入checklist。

3.6.預案管理

反模式3.6.1 

上游流量異常時沒有相應的防雪崩預案

【實例】

服務上游流量突增,導致服務瞬間被壓垮,系統雪崩

【解決方案】

服務必須提前做好防雪崩預案,不然很容易導致整個系統級別的故障

反模式3.6.2 

服務沒有防刷和防攻擊預案

【實例】

線上問題定位時,發現某個線上服務存在大量刷接口的現象,給線上系統的穩定性帶來很大隱患,同時造成很大的資源和成本浪費。

【解決方案】

線上服務,特別是和端交互比較多的服務,設計時就需要考慮好防刷和防攻擊策略,提前做好預案

反模式3.6.3 

下游故障時沒有相應的處理預案

【實例】

下游服務故障,上游服務沒有相應的處理預案,導致被下游拖垮,因爲這種情況導致的大型故障非常多

【解決方案】

下游故障,尤其是下游弱依賴服務故障,需要有相應的處理預案

反模式3.6.4 

故障時預案已失效

【實例】

由於業務迭代比較快,當前對某下游已經從弱依賴變成強依賴,下游故障時,執行降級預案但業務故障並沒有恢復

【解決方案】

定期對預案進行演練,保證預案有效性

3.7.穩定性原則和意識

反模式3.7.1 

對穩定性缺乏敬畏之心

【實例】

以爲服務出故障是正常的,對穩定性不以爲然

【解決方案】

技術同學需要對代碼、線上穩定性保持敬畏之心,不能有任何僥倖心理

一行代碼的bug,就可能導致整個業務癱瘓掉

反模式3.7.2 

故障時沒有第一時間止損

【實例】

服務出現故障時,相關同學第一時間在定位故障原因,沒有第一時間進行止損

【解決方案】

出現故障必須第一優先級處理,第一時間止損

反模式3.7.3 

使用未充分驗證過的技術和方案

【實例】

某服務使用了mq的廣播特性,該特性在公司還沒有在線上被使用過,上線後觸發mq廣播消費代碼中的一個bug,導致mq集羣不可用的故障

【解決方案】

儘量避免使用未充分驗證過的技術和方案

如果因爲某些原因必須使用,一定要有相應的兜底措施,同時控制好接入的節奏

在非關鍵服務上驗證充分後,才能應用到核心鏈路上

反模式3.7.4 

使用新技術時未控制好接入節奏

【實例】

某服務使用了mq的廣播特性,在非核心服務驗證時間不夠的情況下,將此特性引入核心服務,核心服務的流量比較大,觸發mq廣播消費代碼中的一個bug,導致mq集羣不可用的故障

【解決方案】

引入新技術時一定要控制好接入的節奏

在非關鍵服務上驗證充分後,才能應用到核心鏈路上

反模式3.7.5 

穩定性改進方案未及時落實

【實例】

某服務出現故障,覆盤時制定了相應的改進措施,但是未及時有效落實;後該問題再次爆發,又一次服務故障。

【解決方案】

建立改進措施落實的有效跟蹤機制,保證改進措施的有效落實。





基於 Apache Flink 的實時監控告警系統
日誌收集Agent,陰暗潮溼的地底世界
2020 繼續踏踏實實的做好自己


公衆號(zhisheng)裏回覆 面經、ES、Flink、 Spring、Java、Kafka、監控 等關鍵字可以查看更多關鍵字對應的文章。

你點的每個贊,我都當成了喜歡
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章