作者 | 宋旭
背景
監(jiān)控一直是服務(wù)端掌握應(yīng)用運(yùn)行狀態(tài)的重要手段,經(jīng)過近幾年的發(fā)展,阿里蝦米服務(wù)端目前已經(jīng)有 100 多個(gè) Java 應(yīng)用,承擔(dān)核心業(yè)務(wù)的應(yīng)用也有將近 50 個(gè),對(duì)于應(yīng)用的監(jiān)控配置也是因人而異。有的人配置的監(jiān)控比較細(xì),有的應(yīng)用在經(jīng)歷了多人開發(fā)階段以后,監(jiān)控就逐漸疏于管理,有些應(yīng)用的監(jiān)控項(xiàng)最后修改時(shí)間只停留到 2 年以前,早已不適應(yīng)業(yè)務(wù)的發(fā)展。
與大部分團(tuán)隊(duì)一樣,蝦米也有一個(gè)報(bào)警處理群,將內(nèi)部的監(jiān)控報(bào)警平臺(tái)(如 Sunfire 等)的信息通過機(jī)器人投遞到群中,由于監(jiān)控項(xiàng)配置不合理、監(jiān)控粒度較大,每天報(bào)警群都被幾十條甚至上百條報(bào)警通知狂轟亂炸,長(zhǎng)此以往大家對(duì)報(bào)警已經(jīng)麻木,大部分報(bào)警也不會(huì)去處理。
基于這樣的現(xiàn)狀,蝦米 SRE 團(tuán)隊(duì)(SRE全稱Site Reliability Engineering,最早由Google提出。致力于打造高可用、高拓展的站點(diǎn)穩(wěn)定性工程)將工作重點(diǎn)放在了對(duì)監(jiān)控的治理上面,經(jīng)過 2 個(gè)月的研發(fā),構(gòu)建了蝦米全新的監(jiān)控體系。
報(bào)警原因分析
過去的監(jiān)控配置可謂五花八門,由應(yīng)用負(fù)責(zé)同學(xué)配置的一些監(jiān)控大多局限在應(yīng)用整體 RT、QPS 的監(jiān)控和部分業(yè)務(wù)日志的監(jiān)控,報(bào)警發(fā)生時(shí),大部分情況只知道這個(gè)應(yīng)用有了問題,但很難快速定位是哪里出了問題,出了什么問題。一個(gè)新接手的同學(xué)可能需要經(jīng)過查看配置項(xiàng)、登錄機(jī)器、掃描日志甚至去查離線日志等步驟,經(jīng)過十幾分鐘才能定位到問題,有的時(shí)候甚至需要排查個(gè)大半天時(shí)間。
經(jīng)過一段時(shí)間的研究和摸索,我們發(fā)現(xiàn)一個(gè)應(yīng)用如果在穩(wěn)定運(yùn)行了一段時(shí)間以后突然發(fā)生報(bào)警,那么原因通常都是以下幾類:
- 程序 Bug:如代碼問題導(dǎo)致空指針、頻繁 FullGC 等。
- 上游依賴出問題:上游某個(gè)接口出了問題導(dǎo)致本應(yīng)用出現(xiàn)接口超時(shí)、調(diào)用失敗等。
- 單機(jī)故障:某個(gè)容器受宿主機(jī)應(yīng)用導(dǎo)致 Load、CPU 突然升高,最終導(dǎo)致超時(shí)、線程池滿等情況發(fā)生。
- 中間件故障:常見的如 Cache、DB抖 動(dòng)導(dǎo)致一段時(shí)間內(nèi) RT 增長(zhǎng)、超時(shí)增多。不過這里需要注意的是,單機(jī) Load 高同樣會(huì)引發(fā)單機(jī)讀寫 Cache、DB 出現(xiàn)問題。
監(jiān)控優(yōu)化
分析了報(bào)警原因,下一步就是優(yōu)化監(jiān)控。監(jiān)控的報(bào)警可以告訴你出了問題,而好的監(jiān)控是可以告訴你哪里出了問題。我們以前的監(jiān)控通常只完成了第一階段,而不能很好的告訴我們哪里出了問題,要通過一大堆輔助手段去定位。在分析了報(bào)警原因以后,我們就要想辦法通過監(jiān)控的手段來精準(zhǔn)定位問題。
目前蝦米的監(jiān)控分為故障監(jiān)控、基礎(chǔ)監(jiān)控和通用監(jiān)控三類,如下圖所示:
故障監(jiān)控
所謂故障監(jiān)控,就是這些監(jiān)控發(fā)生報(bào)警意味著有故障產(chǎn)生了。我們認(rèn)為一切外在因素如果對(duì)應(yīng)用產(chǎn)生影響,那么必然反應(yīng)在接口的 RT 和成功率上,要么引起接口 RT 升高,要么導(dǎo)致接口失敗數(shù)增加,成功率下跌,如果沒有這種影響,那么這個(gè)外在影響可以被忽略掉。因此我們把接口監(jiān)控作為故障監(jiān)控的一大塊來重點(diǎn)配置,如果每個(gè)應(yīng)用都配置了核心接口的故障監(jiān)控,在排查問題時(shí),就很容易定位是否由于上游應(yīng)用的某個(gè)接口導(dǎo)致了我的應(yīng)用出了問題。
因此我們使用成功率、RT 和錯(cuò)誤碼三個(gè)指標(biāo)來進(jìn)行一個(gè)接口的故障監(jiān)控。特別指出的是,對(duì)于客戶端接口的 RT 監(jiān)控上,我們沒有使用平均 RT,而是使用 Top 75% RT。因?yàn)橄胗盟鼇矸磻?yīng)用戶側(cè)的感受,比如 RT的 75% 分位線報(bào)警閾值設(shè)置為 1000ms,那么當(dāng)這一監(jiān)控項(xiàng)發(fā)生報(bào)警時(shí),意味著有 25% 的用戶請(qǐng)求接口已經(jīng)超過 1000ms。通常這一報(bào)警閾值設(shè)置成用戶不能忍受的一個(gè) RT,比如 500ms 或 1000ms。
在故障監(jiān)控里,我們還設(shè)置了應(yīng)用維度的異常、錯(cuò)誤和消息異常三種類型的監(jiān)控,他們對(duì)服務(wù)器上的Exception和Error進(jìn)行監(jiān)控。這一類監(jiān)控主要用于快速發(fā)現(xiàn)程序bug。例如當(dāng)一次發(fā)布進(jìn)行時(shí),如果這三種類型的錯(cuò)誤增加,那么應(yīng)該可以考慮進(jìn)行回滾了。
通用監(jiān)控
大多數(shù)情況下,應(yīng)用出現(xiàn)的問題都是由于單機(jī)故障引起的時(shí)候,如果某臺(tái)機(jī)器的接口黃金指標(biāo)突然變化、錯(cuò)誤或異常數(shù)量突然增多,而其他機(jī)器沒有什么變化,那就說明是單機(jī)引起的。因此我們對(duì)應(yīng)用的故障監(jiān)控都配置了對(duì)應(yīng)的單機(jī)監(jiān)控,在此處我們還額外引入了 HSF(Dubbo) 線程池滿和 HSF(Dubbo) 超時(shí)兩個(gè)類型的單機(jī)監(jiān)控,是因?yàn)楫?dāng)單機(jī) Load 高、CPU 有問題時(shí),最為常見的表現(xiàn)就是HSF線程池突然打滿,HSF(Dubbo) 超時(shí)數(shù)量增多,這兩個(gè)監(jiān)控同樣可以來輔助定位單機(jī)問題。通過這一類監(jiān)控,我們可以方便地接口報(bào)警是否由某臺(tái)機(jī)器引起。
基礎(chǔ)監(jiān)控
前面兩種類型的監(jiān)控已經(jīng)基本可以定位到故障是否由于程序 Bug、上游應(yīng)用或單機(jī)故障引起的,還有一類就是對(duì)中間件的監(jiān)控,這里我們利用了 Sunfire 的基礎(chǔ)監(jiān)控對(duì)應(yīng)用的 CPU、Load、JVM、HSF(Dubbo)、MetaQ 等中間件的各項(xiàng)指標(biāo)進(jìn)行監(jiān)控。如果因?yàn)橹虚g件故障,此處將會(huì)有明顯的報(bào)警。
報(bào)警路徑優(yōu)化
經(jīng)過對(duì)監(jiān)控的梳理和優(yōu)化,目前每個(gè)應(yīng)用差不過有 30-50 個(gè)報(bào)警項(xiàng),如果所有報(bào)警項(xiàng)用以前的方式投遞的報(bào)警群,那么將是一個(gè)災(zāi)難,完全沒有辦法去看,更沒有辦法快速定位問題。同時(shí),一個(gè)應(yīng)用負(fù)責(zé)人通常只關(guān)心自己的應(yīng)用報(bào)警,讓他去看其他應(yīng)用的報(bào)警也是沒用的。因此我們構(gòu)建了一個(gè) SRE 平臺(tái)來優(yōu)化報(bào)警鏈路,優(yōu)化后的報(bào)警鏈路如下:
我們利用流計(jì)算設(shè)定報(bào)警窗口,進(jìn)行報(bào)警聚合,通過報(bào)警分級(jí)來進(jìn)行決定哪些報(bào)警應(yīng)該被投遞出來,在報(bào)警群精準(zhǔn) AT 相關(guān)的同學(xué),查看報(bào)警群時(shí),可以直接定位到 AT 我的消息,快速提取有用的信息。同時(shí)在 SRE 平臺(tái)支持對(duì)應(yīng)用和上游應(yīng)用一小時(shí)內(nèi)的報(bào)警進(jìn)行分類和聚合展示,哪里出了問題一目了然。我們通過自己的機(jī)器人,在釘釘群里只發(fā)送符合規(guī)則的報(bào)警信息,極大減少了報(bào)警數(shù)量,提高了報(bào)警的可讀性,目前日均產(chǎn)生約 5000 條各種類型的報(bào)警信息,經(jīng)過決策和規(guī)則篩選投遞出的報(bào)警信息約為 50-100 條,而這些報(bào)警是我們認(rèn)為必須要立即處理的報(bào)警。
借助流量調(diào)度
在前面提到很多故障是由于單機(jī)引起的,過去我們排查出來單機(jī)故障經(jīng)常做的就是把服務(wù)停了或者單機(jī)置換,這樣效率極低,實(shí)際上我們需要做的是在機(jī)器有問題的時(shí)候,能夠把它的流量快速切走,再它恢復(fù)的時(shí)候再把流量切回來,如果這一切能夠自動(dòng)化地進(jìn)行就更好了。
我們借助阿里巴巴的流量調(diào)度平臺(tái)(即阿里云 AHAS)可以完美地解決以下的問題:
- 發(fā)布預(yù)熱問題,避免發(fā)布帶來的 RT、Load 升高問題 進(jìn)而引發(fā) HSF 超時(shí)等問題;
- 局部機(jī)器流量過高、受宿主機(jī)影響、慢調(diào)用過多、HSF線程滿帶來的服務(wù)不可用、RT過高等問題。
目前,我們約有 40 個(gè)應(yīng)用已經(jīng)接入流量調(diào)度平臺(tái),每周調(diào)度機(jī)器流量 1000 余次,借助流量調(diào)度平臺(tái)我們可以不再關(guān)心單機(jī)故障引發(fā)的應(yīng)用報(bào)警。
本文作者:宋旭,花名全琮,蝦米音樂技術(shù)專家,2017 年加入阿里巴巴,從事蝦米音樂穩(wěn)定性建設(shè)相關(guān)工作。