系統穩定性治理最佳實踐

系統穩定性治理最佳實踐


穩定壓倒一切,沒有穩定就沒有生成。國家是如此,業務系統也是如此。老子說,“治大國若烹小鮮”,治理系統也是要做到同樣,要掌握火候,精選食材,用料恰當,輔以煎炒烹炸煮,則方能出一盤好菜。


很多同學優先考慮公務員、教師等職業,其中非常重要的一個因素就是這類職業相對穩定。應用系統穩定性也是如此,是所有因素裏的前提。


屏幕快照 2020-02-11 12.55.11.png


試想一下,支付寶經常打不開,你還敢存錢進去嗎?

試想一下,微信經常卡死,你會不會煩躁想罵人?

試想一下,京東一支付就係統繁忙,你慌不慌?


那麼系統穩定性該如何治理?有沒有什麼標準或者可以放之四海皆準的方法論和實踐?


系統穩定性問題


屏幕快照 2020-02-11 12.57.41.png


一個系統穩定性取決於很多因素,同樣也受制於很多因素。

爲什麼豐田可以40萬公里不修,而某些國產車開了1年,除了喇叭不響,其它地方都會響?

爲什麼納智捷不停車郵箱根本加不滿?


類似的,一個系統的穩定性也受制於很多方面,總結下來大致是以下幾點


硬件及網絡影響

這個是指應用的容器層面的影響,包括服務硬件、機房、網絡帶寬等。這類因素往往對於開發人員來說不可控,比如管道工人挖斷光纜、運營商網絡抖動或延遲等。

這類問題一般來說很難預期,也很難針對問題進行專項治理。覆蓋全世界網絡,根本沒有人可以保證網絡絕對的穩定性,也根本無法保障一臺服務器永遠不宕機。


高併發大流量

對於一般的系統來說,流量往往不會成爲瓶頸,一般的中小企業做的都是垂直類、行業類業務,總體覆蓋人羣一般不會很多,百萬級已經是天大的調用量了,大部分的系統估計只有幾十到幾百的QPS。針對初級的訪問流量,尚且不用做高併發大流量的設計,遵循普通的開發準則即可覆蓋99%以上的業務了。


但是針對全球型、全國型的國民級應用,則高併發和大流量是主要要考慮的一個TOPIC,不僅在技術方案上就做重點設計規劃,還需要持續關注和治理專項。

比如微信DAU達到了10億級別,這個量級對所有相關的系統都提出了很大的挑戰。一個全員推送不當,可能導致全國人民微信抖三抖。

比如淘寶雙十一高峯期需要處理66W筆訂單,這個量級是一般的系統根本無法滿足的。


方案設計缺陷

方案缺陷指技術方案或者產品邏輯設計有問題,在滿足一定的條件時,可能不會出問題,但是走了某個流程或者流量到了某個層次就凸顯異常問題。


編碼缺陷

這個是最多的一類問題,開發者由於水平層次不一,有的停留在“能運行就贏了”,有的停留在“能在各種入參變化的情況下運行正常”,有的會“極端流量網絡異常下依然可以運行”,從“面向正確”到“面向錯誤”編程。《致命Bug:軟件缺陷的災難與啓示》的一書有很多例子,都是因爲編碼BUG,導致了超乎想象的災難。比如第一章提到的“0.000000095的誤差奪走28條生命”等故障都歷歷在目。

阿里雲也發生過

編碼錯誤類型比較多,通常有以下一些:

  • 邊界值和異常值未考慮

這是最常見的一個問題,大多數初級開發者,往往僅考慮正確且正常的輸入的情況下代碼合計,而往往忽略邊界條件。比如對入參不做非空校驗、價格不做負數校驗、不做超過列表長度的取數校驗等。這類問題看似很小,但是在極端情況下,往往會引起很多莫名低級的BUG。

還有一類是數據源本身本身就可能是出錯的,代碼沒有對這類數據做處理,則導致在運行期間發生異常。接口設計裏有一個很簡單的原則“外部輸入數據是不可信的”。即在考慮接口設計時,就要充分考慮外部數據的一切可能性,有可能傳遞數字格式的String類型,偏偏就傳遞了一個字符串;預期傳遞一個null的,偏偏傳遞了一個字符串"null"等。

  • 併發異常

這類錯誤相對來說更爲“高端”“隱藏”,在單機的條件下一般不會出現問題,但是到了生產多線程環境可能就會出來。由於在開發過程中,對多線程的測試和調試也相對較少,導致開發和測試期間都不能簡單的復現。比如用戶加入組織後,組織又立即解散了,在併發的情況下,可能組織先解散,然後再出現用戶加入組織的事件,如果不考慮其它因素,代碼處理可能就會產生BUG。

  • 冪等或事務異常

對需要做唯一性約束的數據沒有做約束,比如訂單ID不能重複、用戶名不能重複等等。很多情況需要對數據一致性要嚴格保障。其中重要的兩個就是冪等和事務,這兩個點發生了異常,就會導致很多不一致性,進而產生大量髒數據和錯誤數據。



穩定性治理

穩定性治理的核心三板斧,監控、壓測和演練。


監控

監控如果做到了360無死角,則可以第一時間主動發現系統異常,定位到了解決則是相對明確的。那麼穩定性自然也有很高的保障,可以說監控是穩定性保障的前提。

那麼如何做監控?做哪些監控?這個是每個工程師要細緻思考的問題。監控不僅僅是發一條短信出來,告知工程師“系統異常”,而是應該快速告知工程師,哪個系統的哪個接口出現了什麼樣的異常,越具體,就能夠幫助工程師快速定位問題,也就給工程師止血和恢復提供了更快的可能。


監控的告警方式一般有短信、電話、郵件,或者可以使用釘釘通知、釘釘機器人等方式。


屏幕快照 2020-02-11 13.07.17.png


釘釘羣機器人接入方式也比較簡單,還是非常推薦大家使用的,可以把多個告警源接入到釘釘,統一管理。


應用性能監控

load監控

load監控是對於容器和應用層面的監控,可以監控整個容器水位消耗,對業務負載能夠起一個快速的決策。比如正常情況下。


簡單來說,對於單核CPU,load爲1表示已經滿載了,如果超過1意味着好負荷了,有任務已經無法直接佔用CPU資源需要一直等待,系統也可能即將崩潰。同理,對於多核CPU,load則對應具體的核數。一般來說4核CPU的話,load爲4表示滿載。正常情況下,70%的負荷率是比較正常的,即單核CPU的Load要小於等於0.7。


load詳解文章:https://www.ruanyifeng.com/blog/2011/07/linux_load_average_explained.html


屏幕快照 2020-02-11 11.57.04.png

如上圖所示,用TOP命令即可快速查看當前機器的load,圖中的0.88則表示當前機器的實際負載,對於4核CPU來說,負載算比較輕的。


java線程數


java中線程是寶貴的資源,各種代碼運行後都是以線程的方式來運轉,線程是生產實例的最小單位,因此監控線程數就可以監控java應用的實際運行情況。相對load來說,java線程更純粹,load包含了整個CPU的所有消耗,包括其他系統內置的消耗,而java線程則是統計了實際爲應用本身提供服務的情況。


屏幕快照 2020-02-11 12.08.50.png

特別在多線程的情況下,可以快速發現是否有線程泄露等問題,這類問題往往通過其他指標無法直接觀看。比如發現一個接口的RT已經接近超時,機器load飆升,但是接口本身又沒有發現問題,這時候可以看看線程的行爲。


GC監控


屏幕快照 2020-02-11 12.13.24.png


GC是垃圾收集的意思(GarbageCollection),內存處理是編程人員容易出現問題的地方,忘記或者錯誤的內存回收會導致程序或系統的不穩定甚至崩潰,Java提供的GC功能可以自動監測對象是否超過作用域從而達到自動回收內存的目的,Java語言沒有提供釋放已分配內存的顯示操作方法。


簡單來說,JAVA運行期間的數據是以對象的方式存在的,而對象又存在生命週期,在時刻運行期間會產生大量的對象佔用內存,因此需要有垃圾對象回收的策略,稱之爲GC。

GC監控可以判斷編碼中的對象內存泄露,可以對JVM本身進行,也可以對不合理的編碼方式進行監控優化。


業務指標監控

數據大盤

屏幕快照 2020-02-10 23.04.55.png


屏幕快照 2020-02-11 09.23.13.png


屏幕快照 2020-02-11 09.24.14.png


諸如阿里雲相關的雲服務都提供了大盤的功能,可以監控機器的流量水位等。一些中小公司可以使用開源的工具搭建自身內部系統的監控。

具體可查看鏈接:https://blog.csdn.net/smooth00/article/details/85001823


大盤可以根據業務情況區分,比如訂單創建大盤、用戶登錄大盤、賬單支付成功大盤等,大盤可以幫助從全局角度觀察同比環比趨勢。通過趨勢圖可以對波峯、波谷、毛刺進行分析定位問題和優化系統。比如在突然的流量暴漲和暴跌,可以在數據大盤圖快速定位。


成功率

屏幕快照 2020-02-10 23.09.23.png

又稱之爲“接口健康度”,及在指定時間內成功請求/總請求的比率,這個是接口穩定性裏最重要的指標,可以通過這個指標直接判定系統的可用性。

健康度可以根據自己業務目標設置告警等級,比如某些非核心功能,可能設置低於70%成功率告警,對於某些核心功能,比如IM的會話送達率,則可能設置99.99%以上。


RT值

屏幕快照 2020-02-10 23.13.43.png

接口重要的幾個指標,除了QPS外,就是RT了,RT表示一個接口的響應能力,RT越短說明接口提供服務的效率越高,相反,RT越大則代表提供服務能力越弱,一個系統內部出現多種情況的故障時,一般伴隨的就對外提供能力變弱,響應的就是RT會明顯加長。

因此通過監控RT可以很好的監控一個系統的提供服務能力的強弱,不僅在故障期間能夠更爲直觀,在平常也可以給工程師提供一個性能優化的視圖。


主日誌

除了幾個常規指標外,還有一個指標叫主日誌,即把核心的錯誤日誌都打印到同一個文件,通過關鍵的關鍵字進行錯誤分類,進而實現對錯誤分類和錯誤詳情進行告警,幫助快速處理和解決線上問題,實現免登機器定位錯誤的能力。



DB監控

相對應用來說,DB往往是整個系統的性能瓶頸。優化一個準則,也是儘量把流量擋在DB外。也很容易理解,代碼或硬件問題,可以通過集羣和分佈式來解決,但是所有寫流量基本上都要集中在一個數據庫實例中。因此數據庫crash了往往會造成整體功能不可用。

當然在方案設計時候,可以顯示的優化DB層面的設計,比如讀寫分離、數據緩存、分庫分表等。這個對數據庫的設計在其他內容中介紹,本文還是關注如何做好DB監控。


屏幕快照 2020-02-11 11.38.59.png


QPS

qps 每秒處理的查詢數

QPS和TPS是判斷整體數據庫的核心指標,該指標也表示了當前的數據庫運行能力,當然應用層不好判定具體暴漲業務的時候,可以通過數據庫的SQL來對數據進行定位,輔助定位到異常的SQL語句,進而分析故障原因。


TPS

tps 每秒處理的事務數


慢SQL

數據查詢變慢的一個原因,就是慢SQL,慢SQL顧名思義,就是一條執行很慢的SQL,主要是查詢慢,一般來說SQL查詢都是毫秒級別,到了秒級的話,就是基本慢SQL了。慢SQL嚴重性不僅是本身查詢慢,而是慢SQL會大量消耗數據庫本身的資源,比如數據庫的線程、CPU、內存等,從而使得整體服務能力下降,最終拖垮整個數據庫。


壓測

相對運行期間監控來說,壓測是運行前的一個提前發現問題的操作。壓測也需要做到常規化、持續化執行。壓測可以用自動化的手段來在真實環境下獲得系統的穩定性問題,提前發現系統異常和薄弱環節。

像大型的雙十一,就會用提前壓測的方法模擬雙十一甚至超過幾倍的請求,來進行全鏈路探測系統問題,並及時進行修復解決,這樣當然就不怕雙十一期間的自然大流量完全壓垮系統。也提前做到了心中有數。


屏幕快照 2020-02-11 13.00.06.png


壓測一般用我們上述提及的指標作爲衡量標準,比如load是否到1,成功率是否下跌,主日誌是否出現錯誤等等。


演練

監控發現問題治理,壓測探查系統薄弱瓶頸,而演練則是在生產上真實的創建故障,用來發現系統穩定性、魯棒性和自動恢復性,還能檢測應用負責人是否有快速響應系統異常的能力、止血和修復的能力。


演練類似消防演習,即人工的採取某些措施,比如斷網、停DB、MOCK緩存失敗等。


總結

穩定性治理三板斧:監控、壓測和演練。應用容器三要素:load、線程、GC。業務數據監控四要素:大盤、成功率、RT值、主日誌。DB監控三要素:QPS、TPS、慢SQL。


系統穩定性壓倒一切,只有保障了好了穩定性,才能幫助業務蓬勃增長,因此穩定性治理始終是工程師基本能力之一。

------圖片來自網絡,侵刪

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