每日優鮮監控系統早期情況
系統覆蓋不全
每日優鮮早期只有交易平臺存在一套內部的業務監控系統,沒有推廣到全公司級別。大數據團隊與自己的業務監控,運維團隊有自己的基礎監控。除了交易系統其他業務線的業務監控幾乎為零,很多時候都是用戶告知我們出問題了,而不是我們主動發現出問題了,導致問題發現的時候已經過去很久了。
監控類型不完善
監控內容主要是涉及日志中出現的數據統計,所以對PV、UV、JVM相關監控都沒有,尤其對自身業務的監控幾乎為零,我們無法實時的知道當前接口的訪問量,錯誤率等信息;除此之外我們依賴的zookeeper、mq、redis、數據庫等中間件的監控也基本沒有,所以很難做到深入的排查。不過好在有一套pinpoint可以幫助故障和性能定位。但是這并不能代替業務監控。
監控系統選型和實現
選型
要實現一套監控系統,必須要保證數據的收集、存儲和可視化,然后在基于此實現一套告警系統,最終實現數據的可視化與問題的觸達。
可視化選型
在做監控系統選型的時候,最優先定下來的是可視化,即Grafana這套開源產品,因為其支持多數據源,同時也支持告警規則,除此之外其提供了一套完備的API,我們通過程序調用其API實現了監控數據可視化的自動化流程。
存儲選型
第二個定下來的是存儲系統,監控的數據基本都帶有時序性,所以我們自然而然的朝著時序數據庫(TSDB)方向進行選型。最終定下來的存儲有兩種:存儲業務監控數據的OpenTSDB和存儲中間件監控數據的Prometheus。
選擇OpenTSDB的原因在于我們的業務數據需要長期保留,比如我們現在業務的監控數據已經存儲了一年,大家可以輕易的查到?5.17?,?6.18?的歷史大盤數據。
中間件等監控數據不需要保留太長時間,所以單獨的采用了另一套存儲Prometheus的TSDB,為什么選擇它的,原因是Prometheus擴展性非常高,通過相關的exporter可以快速的開發一套針對性的中間件監控,同時社區也已經支持了很大一部分的中間件的exporter(收集服務暴露監控數據接口)。
數據收集
監控數據的收集從兩方面做的,一方面是提供內存埋點的方式,即我們提供的monitor包,另一方面為了接入了老監控系統能夠平滑遷移到新的監控系統上來,我們支持了基于日志的統計,可以統計pv、異常等信息。
日志收集也兼容原來的方案,即采用flume進行日志采集,kafka進行日志傳輸,日志統計系統進行日志數據消費、統計。
告警系統
為了方便與自研的監控系統實現自動化接入以及與現有的組織人員接入,對告警系統做了自研。
告警系統自動化接入: 業務接入監控,如果該業務在應用中心已經注冊存在,那么監控系統在第一次收到業務發送的監控數據時,會調用告警平臺接口創建告警應用,同時告警平臺會根據App_code從應用中心拉取該app_code下所有相關研發人員,全程自動化。
靈活性: 告警平臺除了自動化接入,也可以手動接入告警,手動維護告警人員,對外提供了告警接口,業務方可以根據自己的需求接入告警發送、消息通知等功能。
告警方式: 在告警系統上線之初支持短信、郵件、電話三種告警方式,去年年前緊急接入了lark,實現了第一版lark告警功能的接入,到現在告警平臺已經對接了多個lark機器人,同時實現了群機器人的告警消息推送。
監控系統的架構

監控系統的實現
業務監控
業務監控采用sdk和日志收集兩種方式進行統計上報,其中monitor中內置了對數據庫連接池的監控、JVM監控、dubbo提供者調用監控、dubbo消費監控等。
對于JVM監控采用內置的ManagementFactory獲取
Dubbo和Http接口的pv和異常監控均采用攔截器的方式,直接集成在monitor中。
機器監控
機器監控的基礎數據來源于運維團隊的Prometheus,通過業務監控上報上來的機器IP拼接PromQL,并將機器的監控與業務監控的大盤集成,業務可以在業務監控大盤中看到自己的應用的資源使用情況。
中間件監控
中間件監控分為兩種方式,早期的redis管理平臺和rocketmq各自基于monitor sdk實現了自己的監控埋點,走的路線跟業務監控相同。
監控系統自身依賴的組件,如hdfs、kafka、opentsdb等直接采用prometheus exporter進行收集,組件內部維護了一組exporter。
監控圖像自動生成
為了監控接入的便捷性,我們實現了監控大盤的自動生成,根據monitor內置的相關埋點進行默認的監控數據上報,如JVM、Dubbo、Http等。通過這些上報數據拼接JSON,同時調用Grafana的創建Dashboard的API接口,自動創建Dashboard,大致流程如下:

機器的核心指標(cpu、內存、磁盤、帶寬),通過應用上報的指標信息中的host tag,生成promql,通過promql從運維的prometheus數據源中獲取,自動添加到大盤監控中。
監控接入全程自動化
為了方便業務快速接入監控,我們除了對監控自動生成大盤之外,還做了其他的處理,監控系統接入全程自動化,自動化過程如下圖所示:

- 監控數據網關觸發安裝filebeat流程,調用ocean平臺的接口進行filebeat推送安裝,實現wf日志的收集。
- 調用告警平臺實現大盤對應的告警創建,告警平臺根據監控數據網關推送的應用名從應用中心拉取該應用下的相關開發人員,實現告警的自動化設置。
- 監控大盤生成,通過業務推送的監控指標數據和告警地址拼接大盤模板,然后調用Grafana的接口實現界面的自動化創建和更新。
- 監控數據網關調用異常網關,實現異常網關對wf日志的top5日志統計
- 監控數據網關調用日志統計,實現wf的error和warning的pv統計以及異常統計
監控系統的推廣歷程
對監控埋點的認知
最開始推監控的時候大家對埋點的認知還比較淺,所以主要是通過日志方式進行接入,對埋點存在抵觸心理。
監控系統分享
監控系統在一次分享大會上做過相關分享,主要分享通用的監控系統的架構是什么樣,我們的Monitor監控實現是什么樣,支持了哪些功能。
在分享會上再一次重點的宣講了一下埋點的重要性,因為只有業務人員對自己所負責的業務最熟悉,所以為了方便第一時間發現問題,以及對自己的業務有全局的監控,那么就需要手動去埋點。以登陸功能為例,我們需要在登陸操作的每一步做埋點,我們需要知道登陸成功的pv,失敗的pv,是什么原因失敗,失敗比例各占多少。
監控系統方面做的改進
Grafana改造
指標分組
指標分組主要是為了方便大家快速定位自己的埋點位置,比如我們有一組與用戶登陸相關的埋點數據,埋點指標名稱統一為UserLogin_前綴,那么在上報之后我們會自動進行分組,將UserLogin_xxx分到同一組下。為了快速定位一組埋點,對Grafana前端進行大盤進行了拆解顯示,可以通過下拉的方式選擇自己的埋點指標組,然后會過濾掉無用的展示,只展示該指標組下的內容。

指標搜索
Grafana Git上很多人都對指標查詢這個功能有需求,不過官方沒有打算做,隨著業務指標數量的遞增,排查起來非常麻煩,為此,除了可以通過指標分組功能來實現過濾之外,還對指標搜索功能做了實現,可以通過搜索具體的指標來查看具體的單個指標。

分時段告警
不同時段的指標的數據、趨勢是不同的,有些業務基本上晚上都沒有什么量,為了使得告警更準確,實現了第一版的單時段告警,可以實現在指定時間段內才會對指標進行監控。
這種方式已經滿足了大部分的場景,但是業務是多樣性的,指標數據、趨勢也存在多樣性。因此實現了第二個版本,分時段、分策略告警。咋不同時間段可以配置不同的告警策略,從而使得告警更加準確,更加的人性化。

同環比
Grafana的指標圖根據不同的數據類型,配置、查詢方式等都不相同,Grafana的OpenTSDB數據源前端指標圖默認無法將不同時間段的數據放在同一個指標圖上,為了增加同環比的功能,對OpenTSDB的查詢模塊在前端做了擴展。做法如下:
- 對指標查詢做標記,標記是否為同環比查詢
- 查詢時對時間進行計算
- 渲染前對時間進行計算
- 最終達到將不同時間段的數據展示在同一個指標圖上。


告警分布式
Grafana官方的告警策略是不支持分布式的,因此擴展了其分布式告警的功能。
第一版分布式告警
在告警配置數量還在上百個、上千個的時候。在這個階段,直接在數據庫中加了一張鎖表,用來處理分布式告警,發送告警前先獲取鎖,獲取成功則繼續發送,如果獲取失敗,取消告警的發送,即誰拿鎖誰發送。同時引入了鎖檢查的任務。
第二版分布式告警
隨著接入的應用和指標數達到了一定的量級,配置的告警策略也翻了好幾倍,數據庫實現的鎖表出現一定的瓶頸。因此換了第二版本的實現,即對查詢的告警策略數據進行拆分,每個節點跑一部分,實現分布式告警。
告警平臺
告警回執、告警統計
針對告警信息做了定制化,添加告警回執、告警處理等功能,實現告警跟蹤、溯源。

告警回執
異常日志報出來
直接將出錯內容通過告警發出來,業務方可以快速定位問題。默認取出現頻率較高的top5異常。

異常推送
監控系統未來方向
當前監控系統數據收集方面還是分鐘級別,機器指標是十秒級別,無法發現峰值的qps,因為接下來的方向考慮加入秒級監控,實現分鐘和秒級監控的靈活切換,需要的時候開通秒級監控,平時使用分鐘級監控即可,當然,因為秒級監控很耗費性能,所以也可能單獨的在諦聽平臺去做。
引入AI算法,對歷史數據進行分析、趨勢分析,實現告警的智能化,提前預知告警,防患于未然。
此外當前可觀測技術已經越發趨于成熟,Metric、Logging、Tracing逐漸走向統一,三者可以相互跳轉、幫助研發快速定位問題,也是我們值得思考的方向,當然我們現在也在逐步的將三者通過一些手段串聯起來,加快問題的定位能力。