22世紀真實鏈路式監控設計理念分析
淺談最前沿 運維22世紀真實鏈路式 監控報警 設計理念 51CTO 主講老師:大米哥
本課程大綱概述
1: 通過真實案例 看清 不準確的監控報警帶來危害
2: 詳細分析 一個運維 在分析排查故障時候的過程細節 (同樣基於真實案例)
3:運維真實鏈路式監控 的基本理念和思路
4: 本篇分享課程 總結篇 (給出大家一個 完整的框架圖)
1: 通過真實案例 看清 不準確的監控報警帶來危害
做過運維相關工作的朋友都知道一個詞 , 7*24 也就是說 咱們當運維的 為了維護線上叢集的穩定 維護企業產品的穩定
我們需要本著一個無時無刻 都監視著整個線上環境的穩定狀況 這樣一種精神, 這也幾乎成為一個好運維的"基本素養"了
那麼為了達到這樣的目標 , 自然 一套完善的監控系統 就首當其衝的 成為運維工作之中的重中之重了
其實任何一位公司的員工的都明白這個道理, 作為一個當下的網際網路企業, 無論其規模大小, 核心線上產品都是作為 一個企業的靈魂
而由企業 通過常年累月所積累下來的 使用者群 以及 使用者固定的線上流量 這都是最最寶貴的資源
再說的通俗點, 流量 日活 這些都是可以跟金錢 收益 直接劃等號的
所以說 , 一旦 線上生產環境出現故障的時候, 所有使用者都無法使用你的產品的時候, 這對企業來說 是最最最致命的
這可比開發人員 寫錯幾行程式碼邏輯, 測試工程師 忘了測試某條功能 , 銷售人員 丟掉幾個客戶 還要嚴重的多的多的多!!
不是大米哥在這兒危言聳聽 , 很有可能半小時的 P0故障 (P0 P1 P2 P3 )能讓整個企業大傢伙半年的辛苦努力 付之東流
有一句話說的好,咱們運維也可以套用一下 : 叫 辛辛苦苦三十年, 一夜回到解放前
接下來 大米挑出 之前慘痛的真實經歷 再給大家舉兩個例子
真實案例一: 10年前 在某家跨國大型網際網路業務託管公司(雲端計算平臺) 大米哥那時候所在的運維團隊 負責著國外 近7000+伺服器(包括物理機和虛擬機器和所有其他裝置在內)
企業的業務非常的龐大, 通過租賃的形式 託管著全世界(主要集中在歐洲 和 北美) 大大小小200多個入口網站 有視訊的 有音訊的 有多媒體 有廣告 有論壇 有遊戲 有足球 還有×××等等繁多
有那麼一天的夜裡,突然整個團隊的報警電話響起(記得應該是 春節後不久),這是P0級別的報警, 於是運維們全都爬起來處理故障
那一次的故障 所有人 都是先檢視報警資訊, 記得報警資訊當時 最少在郵箱中 也有 近200多條!!
(在那個年代 運維技術還很落後原始, 且監控體系遠遠不及現在的完善 , 自然排查故障就更困難更費時 )
當時的故障原因很隱蔽 一個運維團隊 當時花費了近60分鐘 才最終確定了問題所在
故障雖然最終解決了, 但是發生故障的所在地 是在國外,正處於白天 客流高峰期, 最終造成的瞬時損失 以及後續的影響 按照合約 需要賠付給客戶(按秒計費)近十幾萬美金! , 這佔據了當時年度營業的近十分之一啊 (那時候的企業 尤其外企 對於服務保障 使用者的利益 還是非常尊重重視的 所以 賠付的力度很大 這麼多年過去了 回想起來 還是挺值得敬佩的)
真實案例二: 4年前 在一家網路遊戲公司, 那時候 大米是作為 運維架構師 負責著整個叢集的設計和維護 以及人員的管理
其實隨著 很多年經驗的累積, 在監控報警方面 通過運維工程師們 以及 運維開發的不斷努力 已經進步了很多很多了
記得當時 監控報警系統 由專們的2個Devops 和 1個運維 一同協作搭建 , 按照報警級別, 報警種類 歸納分類 各種去重 各種自動化整合 確實跟10年前那會 不可同日而已了
不過 遊戲公司 相比其他網際網路公司 是有很大的不同, 主要是體現在 高強度的即時的使用者服務上 即時即時 這個詞可就要了命了
玩過遊戲的朋友 都知道一個叫做 副本 的概念把?? 網遊中的副本 在技術的角度上, 其實就是特殊開闢的一類程序 ,副本中的程序進行單獨的資料結算,結合快取技術(redis memcache magoDB ) 最後再彙總到 玩家角色的資料中(mysql)
(補充知識 網路遊戲 會大量使用 快取的機制 主要是為了將頻繁不斷的 使用者資料傳輸 加快速度 且 保證資料的不丟失)
但是 玩遊戲的使用者 都是很有情節的 任何一點點的 物品損失 都是不能容忍的 (丟掉一件心儀的裝備,有時候可比丟了一打現金 還憤怒)
有一次 某一個區服所在的 物理伺服器 出現了故障報警, 級別很高 (P1)
但是由於 監控系統已經比較完善了, 於是 運維們 僅僅在15分鐘內 就通過相對準確一些的報警資訊中 定位了故障所在 且解決了問題
當時是區服伺服器的 幾個副本程序出現了 OOM的狀況,造成程序假死 , 運維人員 迅速把相關使用者快取資料匯出,併成功恢復了玩家的資料 ,重啟了程序恢復副本
其實 這已經是 速度很快的 問題排查+處理了, 但是當時 還是後續產生了 意想不到問題
雖然 玩家在副本過程中的資料沒有損失,但是 由於往家數量多 15分鐘內 先後進入副本的玩家 有400多人, 而副本進入的當日次數 是有限制的 ,且副本最終的獲利 很多人也沒有得到結算 這些玩家中
後來就有一些玩家 在各大論壇進行了嚴厲的投訴 甚至直接找上門來理論, 最後還是給公司的形象造成了不小的損失
後來運維們在總結的時候, 覺得還是監控報警不夠100%的準確 和 即時, 如果 能把排查解決故障時間 縮短到 3-5分鐘內, 那麼損失就會小很多
2: 詳細分析 一個運維 在分析排查故障時候的過程細節 (同樣基於真實案例)
通過前面兩個例子 我們看得出 在緊急狀況之下, 監控和報警資訊 是運維唯一能依賴的 搶救線上環境的最直接救命稻草
我們也可以看得出 , 由於報警資訊的普遍不準確 給運維在排查故障的時候 帶來了很多很多的麻煩 和 誤導
接下來 我們再通過一個真實的案例 詳細分析過程 來看下
晚上11點鐘 監控系統報警了, 累了一天的運維工程師 剛想躺下休息會 , 結果就被吵起來了 ...
我的媽呀 公司的APP完全打不開了 這是P0級別的報警啊!(監控報警的最高級別)
於是乎 慌忙起身開啟電腦,檢視具體的報警資訊, 發現 100多封的報警郵件/簡訊 都塞滿了 , 於是開始排查問題
從報警郵件中開始過濾, 其中有 如下一些內容
使用者QPS報警: 某某介面流量驟然下滑
HTTP返回碼報警: 某某介面全都返回 5xx了(502 503)
CPU報警:某某叢集中 CPU一路飆高 快無法響應了
記憶體報警:各種OOM了
硬碟報警:大量錯誤日誌導致硬碟塞滿 ,還有其他各種硬碟分割槽滿報警
日誌報警:這裡的內容就更"豐富"了, 各種程式碼error/ warining
資料庫報警:各種訪問連線數飆升 過高資源使用
連線數報警:負載均衡 反向代理 程式碼叢集 大量waiting_connections 少量出現半連線等等
各種快取叢集報警: 大量併發連線, 過高資源使用, 主從同步緩慢 記憶體佔用嚴重 等等
於是 苦逼的運維工程師 開始旅行自己的"神聖職責"了, 救火啊 排錯啊 趕快想辦法恢復線上請求啊啊啊啊~~
運維一般的反應是(尤其是當前階段)啊呀 系統全面癱瘓了,是不是遭到***啦??
於是趕快去看外層流量圖(內部監控nagios prome zabbix , 監控寶), 奇怪了 不對啊, 最外層流量圖顯示 並沒有看到 超大的併發連結數 或者新建連線數啊
雲產品的安全防護 也沒有報出 遭到某某種類(如 DDOS, CC)***啊 , 那可以確定 不是***了
那接下來看下 資料庫吧, 因為根據以往的經驗, 越是後端的叢集 越容易導致問題的出現
看了一下,果然 資料庫資源利用過高, 連線數過大,有慢查詢的現象
把資料庫重啟一下 試試吧(運維最大的利器 ), 重啟幾次之後,連線數和資源降下去 但是又迅速飆升回來 感覺沒啥作用 看來不是資料庫的問題
那麼會不會是人為因素呢? 比如 哪個不懂事的開發人員 偷摸的晚上加班 未經許可上線功能了?
於是 趕快去看 釋出系統記錄(持續整合), 結果 今晚並沒有任何線上程式的更新
但是也有可能是 開發人員 沒有嚴格走持續整合的釋出流程 自己手動上線呢?(SUDO)
乾脆 把程式碼回滾到昨天 試試看把 , 回滾之後,問題依然沒有解決, 看來不是程式碼釋出問題
那麼有沒有可能 是哪臺做負載均衡的機器 掛了 導致請求失敗堆積呢?
看了一下負載均衡的所有節點, 發現健康檢查的記錄是OK的,也沒有出現任何腦裂之類的現象 看來問題也不在這兒
接下來看看硬碟使用狀況吧, 哎呀 核心叢集的PHP錯誤日誌 (Nginx) 把分割槽寫滿了, 這肯定是根兒啊, 於是乎 運維很熟練的
把日誌移走,重啟了所有核心叢集的服務, 哈哈 一下子服務從5xx的返回碼, 又變回200了, 太高興了 終於解決了問題
可是呢。。。。。好景不長 沒過多長時間, 又開始報警了。。。。 運維徹底奔潰了
問題到底在哪裡啊。。。 疑????? 這裡有一條硬碟報警 看著特殊一些
是快取叢集分割槽滿了。。 於是 趕快上去看 redis日誌, 發現大量的 REDIS_ERR , RDB_failures, 終於終於找到問題的根兒了。
由於快取叢集硬碟滿,造成redis的RDB同步失敗, 進而變成只讀不寫的狀況, 這種情況下 從庫無法再被更新,於是乎 主程式由於後續無法在
快取讀到最新的資訊,進而去訪問關係資料庫, 且量越來越大(),到最終 完全不走快取 而關係資料庫 在這種情況下 ,很快會被消耗殆盡 造成請求的返回緩慢 慢查詢
接下來 主程式層由於動態請求 無法正常響應 而造成堆積 返回碼大量非200請求, 各種錯誤日誌大量產生 CPU標高 ,記憶體耗盡,使用者QPS下降 等等
真的是一波三折啊...
監控報警
3:運維真實鏈路方式監控 的基本理念和思路
通過上面一小節 ,詳細的剖析 運維通過 監控報警資訊分析 故障原因的時候
我們看到了一個很嚴重 且普遍存在的問題
由於監控報警資訊 的數量龐大 且定位問題作用過小, 給運維工程師排查緊急故障 造成了很大的不便 以及寶貴時間的浪費(這裡是最好的體現 時間就是金錢)
如何大幅度的提高 報警準確性 目前是個大企業 面臨的最急迫的問題 (其實 這已經不單單是運維面臨的問題了)
相信所有的運維工程師們 都在期待著一款絕妙的 完美的 監控報警工具 能幫我們把問題徹底完美的解決
但是很遺憾 , 雖然現階段 市面上的 各類 開源監控軟體, 商業監控平臺 不斷的迭代出新, 不過 我很肯定的告訴大家 經過這麼多年的實際檢驗
目前尚未有一款成型的監控產品 能真真正正的幫運維 幫企業 把監控報警做到咱們期望的 完美境界
不過呢, 在不久之前 出現了一個聲音 一個口號 , 或者說是一種新式的監控理念出現了
這就是 我跟大家所要介紹的, 咱們的主題, 真實鏈路式監控 理念
其實這個理念 也並不是由大米哥(我本人)第一個提出的, 我也是在一次和面試官的交流過程中 聽到過這個詞彙
當時我很激動, 立刻去搜索相關的資料,但是很鬱悶的是, 發現這個新式的監控理念 到現在也僅僅停留在 口號的階段(或者說 稍有思路)
並沒有真正的開始研究,更不要說實現在運維生產環境上了
雖然有些遺憾, 但是真實鏈路式監控 這個提法, 尤其是 "鏈路" 這兩個字 給了大米很多的靈感
接下來 我結合自己運維11年的生涯 給大家講一下 對於 真實鏈路式監控 的設計理念思路
理念一: 完整化終極監控取樣採集
記得大米在之前推出的 prometheus監控課程中 也提到過 監控採集
上面這張圖 大家應該還有印象, 不管是對於什麼監控, 即便是 未來的真實鏈路式監控 也一樣離不開 監控採集
資料的採集 對監控系統來說 是一切的源頭
不過 對於 真實鏈路式監控 在設計理念上, 對於採集的強度 就更勝一籌了
我們需要把幾乎所有的跟監控相關的資料 都要採集到, 這說起來容易 但是真想實現 是異常的龐大 且有點不可想象
舉個例子來說:
就拿Linux作業系統中的一項指標CPU來說吧, CPU在Linux核心功能的劃分下 會呈現八種狀態
分別叫做 使用者態, 核心態, 空閒態, Nice態, IO等待,硬中斷, 軟中斷,虛擬化
( CPU在Linux當中, 是以這八種狀態 , 按照時間片使用分配時長的方式 通過累積 + 百分比瞬時計算 來呈現 CPU各種狀態下的百分比的 )

如上是 咱們最熟悉的 TOP命令輸出
每一種狀態的CPU 對於分析作業系統的效能指標 都十分重要 (在低端的運維技術層面中, 可能只關注 使用者態 和 核心態)
那麼 CPU還會劃分出 每一個CPU核 , 整體監控完整CPU 很多時候不夠細緻, 每一單核的狀態 有的時候 也會影響全域性
(曾經遇到過 redis 單程序 跑滿32核CPU其中的一核,雖然整體CPU監控體現很閒,但是這一個程序造成了無法響應,最終引起故障)
所以說, 我們簡單的來算一筆帳 , 在我們的 真實鏈路式監控 監控採集理念下, 光是一個CPU項
就得有 1(一個完整CPU) 16(假設16核) 8(八態)* 100(假設叢集就100臺伺服器) , 這就是 12800 個小監控項....
真實鏈路式監控 的第一個理念 就是對 監控資料取樣的超高完整性要求, 不可以遺漏任何一個 在叢集中 有可能造成影響的 指標
不過 我們也看到了, 完美這個詞 光從量上 就已經很龐大 有一點讓人望而卻步
這還只是一個CPU, 還沒提到 記憶體 硬碟 IO 日誌,程式 資料庫呢。。。。
理念二: 監控資料 靈活向量化建設
大多數的監控工具/平臺, 對於監控取樣資料的 都是一種 "分而治之 各自為政" 的處理形式
舉個例子來說吧 一般的監控 在資料採集之後, 根據工程師定義好的規則 (各種大於小於臨界值) 然後產生監控輸出資訊 和 報警資訊
如上圖所示, 每一項監控專案 都是分開採集 分開計算 分開顯示和報警
我們的第二項 真實鏈路式監控 的設計理念 需要建立一種 完美的 監控資料 向量化
什麼意思呢?
就是讓 所有采集過來的 一個一個的監控專案 不再是孤立的 不再是分開
且 讓每一個子項 都變成可被其他子項 後者是整個監控系統 可識別 可呼叫的 狀態 (區塊鏈的理念 )
可以實現彼此的溝通(通訊)
舉個簡單例子來說 我們要求 所有監控項 能呈現如下這樣的狀態
理念三: 向量化的監控專案 建立層級連帶+責任追溯關係
這個第三個設計理念 有點不太好理解了, 聽大米好好講解哦
什麼叫做 層級連帶+責任追溯呢?
我們通過之前的第二小節課程 給大家講的那個實際例子 還記得不?

由於一個快取上的硬碟分割槽滿了, 引起 其他各個地方連帶的問題和報警, 並最終導致了 致命的資料庫癱瘓 引起P0級別的故障
其實從這個例項 我們看出, 一個問題的引起 會引發一種連帶式的 或者說是 連鎖反應
總結一下 是這樣的順序: 硬碟分割槽滿 -> RDB同步失敗 -> redis從庫失效 -> 程式大量訪問轉向 -> 各處請求WAITING堆積 -> 資料庫資源繁忙 -> 資料庫掛點 -> 最終導致使用者請求無法響應 QPS嚴重下滑 -> P0報警的產生
這樣的 一種按照順序 一步一步 連帶 的發生故障,就叫做 層級連帶
而我們在這個例子 不難發現, 不管這種故障連帶有多少層, 其實都有一個問題的起點 那麼按照責任制的劃分 追溯到源頭 其實它就是原因
這個才是關鍵!! (最左邊的硬碟問題)
而且 運維在排查解決的時候, 由於監控系統無法完美的提供支援, 這種源頭一般很難第一時間發現 (除非是一個公司的 一個老運維 面對同樣發生的問題 有可能能意識到 但這不是我們所追求的目標, 畢竟企業是鐵打的營盤 流水的兵, 不可能總是依賴老運維 也不可能總是僥倖心理 盼望著每次都是同一個原因造成問題)
那麼對於 第三個設計理念, 我們需要 真實鏈路監控 能提供類似如下的功能
理念四: 左推式+上推式 +評估式 + 分散式 最終形成 真實鏈路式監控
這一小節中 我們需要為 真實鏈路式監控 再貢獻四項 模糊一些的 但是很重要的 演算法支援
那麼接下來 分別介紹著幾個詞是什麼意思
1) 什麼叫左推式呢? 為了說明這個,需要先簡單介紹一下 企業標準五層線上架構

如上圖所示,五層線上架構 是當下企業運維架構的一種標準, 線上指的是處理使用者線上的請求
(不能說 100%所有企業都是完全按照這個架構走的, 但是當前網際網路運維線上架構的基本形式 差不多都是這個模式)
其中可以看到 由左向右 流量的傳遞過程 以及每個層級涉及的技術 ,一直推到最右邊的 關係型資料庫層
那麼結合這張架構圖 , 我們可以解釋一下 什麼叫做 左推式了
意思就是說,隨著流量由左向右 逐層深入, 越是靠右邊的層級出現故障,那麼它所引起的連鎖反應越嚴重,也更可能帶來全線的癱瘓
舉個例子來說, 最左邊的洪流層負載均衡假設Down了一個節點, 因為有HA的存在 會被快速轉移, 充其量就是加重了一些 其他LB節點的負擔而已, 倒並不至於影響全域性
但是 如果是最右邊的關係資料庫down了一節點,且這個節點對應的庫和表 在業務級別中很重要, 那麼一定會引起全面的業務癱瘓 ,而且整個左邊的叢集都會被牽連進去
所以 對於真實鏈路式監控, 符合左推式的演算法 , 就應該 具備這一種判斷,看看報警項 是處於哪一個層級, 然後 加入類似Linux nice值的一種東東 ,對報警的嚴重性 加入綜合判斷
2) 接下來說一下 什麼叫上推式
上推式解釋起來 要容易的多
在企業整套架構當中, 其實還可以按照 類似於 OSI七層模型的方式 ,由上向下的分級
最下層 我們可以定義為 網路層
中間層 我們可以定義為 OS系統層
中上層 我們可以定義為 系統服務層(開源服務 FTP DNS NGINX)
最上層 我們可以定義為 應用程式層 (開發的事)
這種樹形分層的模型, 是為了說明一個問題, 越靠下層出現故障,越有可能影響面越大
舉個例子
網際網路叢集 ,網路其實是底層,隨著雲端計算的出現,可能運維都不需要太關注了,但是一旦網路出現問題 , 比如整個IDC,或者整個雲可用區網路出現癱瘓
連PING都不通了, 那什麼也不用說了,其他的地方也不用排查了,這個問題 就一定是導致全部產品癱瘓的源頭
最上層 是應用程式層, 程式出現了一些問題, 比如 剛剛上線的一項小功能, 無法正常使用了, 那麼可能也只是影響了一小部分使用者體驗而已, 到不一定就會影響全域性
所以說 這就是給大家的第二個 真實鏈路監控的 理念, 樹形結構的 上推式演算法
3) 接下來 咱們說一下 什麼叫做評估式
評估式的意思是說, 在監控的過程中, 如果同時出現問題是處在同一個層級 (不管是按照 前面所說的 左右分, 還是上下分)
在同一層級中, 並行出現的問題, 也需要有不同的判斷依據, 也要根據業務種類的不同 有所區分
舉個例子來說 , 假設 都是在 系統層面中 同時出現了 CPU 和 記憶體的報警 , 這兩項報警 都屬於 上推式當中的 OS系統層
而CPU 和 記憶體 對於不同密集型的叢集 它的分量是不一樣的
比如 在PHP(核心程式碼層) 這一般情況下 屬於 CPU密集型 ,所以CPU的比重要高於記憶體 (排除一些 PHP程式碼(也包括其他程式碼)例如分配變數的不健康 導致的記憶體溢位等極端例子, 總體來說 健康的程式碼 重於計算 而不是過度消耗記憶體)
又比如 在大資料叢集中, 記憶體的比重 明顯要高於CPU (大資料行業有這麼一句話, 記憶體決定生死, CPU決定效率), 也就說 Hadoop 記憶體如果不夠了,可能直接導致MR任務掛掉, 如果CPU不足呢? 可能僅僅是執行速度變慢了
通過上面的兩個 例子, 我們可以看出 評估式演算法 的重要性, 也就是說 同一類的 或者 同一層級的 報警專案, 根據不同的應用種類, 真實鏈路監控 需要具備 靈活評估判斷的能力(說起來簡單 實現起來很難)
4) 最後 再來說下 分散式
分散式這個詞一出, 大家理解上應該不會有問題吧? 聽得很多很多了
關於什麼是分散式, 我這兒不再給大家囉嗦它的底層含義, 感興趣的朋友 可以自行查閱資料 多的是
大米在這兒 只是介紹一下, 為什麼需要 把分散式的用法 融入到 咱們的 真實鏈路監控當中
前面在理念一的時候, 就跟大家說過了, 僅僅是資料採集一項 在量級上 就是非常巨大的(12800)
所以說 可想而知 如果真的要搭建出 真實鏈路監控的 平臺, 在資料儲存上, 以及計算方式上 需要依賴分散式儲存 和 分散式計算
(順帶一提的是, 現階段 對於分散式儲存和計算 支撐最好的 自然是各種Hadoop大資料生態圈(實時性 YarnHadoop+spark HBASE STORM) ,不過 時代和技術的變遷是很快的, 我們並不知道 當有一天 真實鏈路監控真的用在生產環境的時候, 分散式是否還是現在這個樣子 這就不好說了)
總結篇:
通過上面三個小節 , 我給大家分享了 未來真實鏈路式監控 的一些設計理念
其中很多的理念 其實都是我個人根據十多年運維架構的經驗 所提出的 並不是所謂的官方定義
其實時代在發展 運維技術 企業架構 也在不斷的更新迭代,實事求是的說 有一部分提到的設計理念
有可能會隨著時間的推移, 也需要進行改良 需要再提出更適合的思路和方法 這都是不可避免的
不過 作為一個老運維, 經過十多年運維生涯的風風雨雨 , 對於這種完美監控的誕生需求 是始終不會變的 也是不會錯的
最後 我們把上面所有的 關於 真實鏈路監控的知識點 設計理念 綜合放在一張圖中 大家可以多多體會一下吧 ^_^