斗魚 Juno 監(jiān)控中心的設(shè)計與實(shí)現(xiàn)
前言
伴隨微服務(wù)的推廣,程序粒度的日趨小型化,服務(wù)數(shù)量逐漸增長,需要更多的關(guān)注服務(wù)本身的監(jiān)控,服務(wù)上下游服務(wù)情況,以及相關(guān)數(shù)據(jù)源中間件的狀態(tài)。我們需要更加多維度服務(wù)監(jiān)控,能夠?qū)Ψ?wù)調(diào)用鏈路進(jìn)行可視化、對目標(biāo)服務(wù)調(diào)用時客戶端與服務(wù)端的實(shí)時監(jiān)控。在 Juno 監(jiān)控中心,我們嘗試解決這些問題。
為什么需要監(jiān)控中心
? ?
在行業(yè)內(nèi)越來越多的公司需要開發(fā)人員懂得服務(wù)器基礎(chǔ)架構(gòu)、操作系統(tǒng)、網(wǎng)絡(luò)、語言特性、業(yè)務(wù)整體架構(gòu)、面對線上問題快速分析快速定位、還包括服務(wù)性能調(diào)優(yōu),對這些方面的要求就是 Google 倡導(dǎo)的 SRE(站點(diǎn)可靠性工程師)。這項(xiàng)工作依賴于很多工具才能順利完成,例如日志系統(tǒng)、發(fā)布系統(tǒng)、監(jiān)控系統(tǒng)等等。
在斗魚微服務(wù)管理系統(tǒng) Juno,其中的監(jiān)控中心的設(shè)計就是為協(xié)助開發(fā)人員進(jìn)行高效的服務(wù)穩(wěn)定性維護(hù)工作,完成對微服務(wù)系統(tǒng)的健康支持:
水位瓶頸,在斗魚進(jìn)行全鏈路壓測,通過監(jiān)控系統(tǒng)可以找到服務(wù)鏈路中的瓶頸,了解核心項(xiàng)目的具體水位;
故障預(yù)防,采用環(huán)比和同步數(shù)據(jù)進(jìn)行服務(wù)健康波動分析,進(jìn)行一定程度上的異常預(yù)防;
故障排查,線上故障快速定位,給出服務(wù)調(diào)用鏈路,從監(jiān)控異常數(shù)據(jù)開始分析,排查影響范圍,定位問題觸發(fā)點(diǎn)。
?
主流產(chǎn)品差異性
只針對市場上的免費(fèi)解決方案進(jìn)行分析,目前分析的 Zabbix、Nagios 都比較偏向于基礎(chǔ)運(yùn)維監(jiān)控工具。Juno 監(jiān)控中心是 Grafana 和 Prometheus 的最佳實(shí)踐之一,更偏向于業(yè)務(wù)監(jiān)控。
| ? | 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|---|
| Zabbix | - 數(shù)據(jù)采集方式多樣 - 可用性高 - 歷史數(shù)據(jù)可查詢 - 安全審計 | - 性能瓶頸 - 二次開發(fā)難度 - housekeeping 的數(shù)據(jù)庫壓力 |
| Nagios | - 配置靈活 - 多樣性的報警條件設(shè)置 | - 無歷史數(shù)據(jù)存儲 - 配置復(fù)雜 - 控制臺功能較弱 |
Juno 監(jiān)控中心簡介
Juno 監(jiān)控中心理念
Juno 監(jiān)控中心有三個核心理念:容量水位;監(jiān)控預(yù)警;快速定位。
容量水位
容量水位:服務(wù)可以承受多少的 QPS。通過全鏈路壓測的方式獲取對外提供 API 在微服務(wù)體系中的整體鏈路,首先探測服務(wù)本身可承載的容量是多少,針對危險水位進(jìn)行數(shù)據(jù)采集,并以此作為流量變化后的擴(kuò)容依據(jù)。

監(jiān)控預(yù)警
監(jiān)控預(yù)警:多個維度進(jìn)行監(jiān)控預(yù)警。
服務(wù)響應(yīng)時間、QPS、成功率這三個基礎(chǔ)維度進(jìn)行告警配置;
對各指標(biāo)根據(jù)歷史數(shù)據(jù)進(jìn)行環(huán)比計算預(yù)警;
進(jìn)一步根據(jù)服務(wù)各自的水位進(jìn)行兜底告警。

快速定位
快速定位:在故障發(fā)生是,通過響應(yīng)速度來判斷在哪個服務(wù)出現(xiàn)了問題,通過 TOP 指標(biāo)和上下游鏈路解析快速定位異常點(diǎn),再進(jìn)一步結(jié)合異常服務(wù)上下文監(jiān)控數(shù)據(jù)和日志數(shù)據(jù)進(jìn)行錯誤分析。在異常恢復(fù)后也可以通過監(jiān)控進(jìn)行判斷服務(wù)狀態(tài)。


Juno 監(jiān)控中心特點(diǎn)
| 部署簡單 | 依賴 ETCD 和 prometheus 進(jìn)行部署,數(shù)據(jù)采集和服務(wù)治理采用基本一致的組件 |
|---|---|
| 插件支持 | 結(jié)合 Juno Agent 進(jìn)行數(shù)據(jù)采集插件化配置 |
| 管理后臺 | 在 web 界面進(jìn)行配置定制化加載,定制化的交互 |
| 配置監(jiān)控 | 客戶端配置信息監(jiān)控;管理后臺直接展示配置在哪些實(shí)例上被哪些服務(wù)使用 |
| 自動發(fā)現(xiàn) | 基于 Juno Agent 的心跳上報進(jìn)行監(jiān)控數(shù)據(jù)節(jié)點(diǎn)發(fā)現(xiàn) |
| 告警配置 | 服務(wù)告警條件配置豐富 |
Juno 監(jiān)控中心設(shè)計
總體設(shè)計
層次設(shè)計
下圖描述 Juno 監(jiān)控中心的總體設(shè)計,從下往上分析:

采用 Jupiter 框架構(gòu)建的客戶端,服務(wù)啟動之后會在 ETCD 中寫入監(jiān)控的 KEY;
Juno Agent 服務(wù)監(jiān)聽到監(jiān)控的 KEY,生成 Prometheus 的 Target 配置;
Prometheus 根據(jù) Target 配置讀取 Jupiter Client 的監(jiān)控數(shù)據(jù);
在 Juno Admin 內(nèi)嵌 Grafana 讀取 Prometheus 進(jìn)行監(jiān)控數(shù)據(jù)展示。
客戶端設(shè)計
下圖簡要描述 Jupiter 客戶端(Jupiter Client)的部分:

用戶構(gòu)建 Jupiter Client,在 ETCD 中寫入監(jiān)控的 key-value;
同時 Jupiter Client 提供一個自建的 Prometheus
Pushgateway(http://xxx.xxx.xxx.xxx:9999/metrics);
Prometheus 由 Juno Agent 生成 Target 配置后周期性的 pull 監(jiān)控數(shù)據(jù);
服務(wù)端設(shè)計
核心流程就是 Grafana 增加 Prometheus 數(shù)據(jù)源,Prometheus 通過 Juno Agent 生成的配置進(jìn)行監(jiān)控數(shù)據(jù)拉取。這里 Juno Agent 僅僅只用于 Prometheus 配置的生成,不上報任何的監(jiān)控數(shù)據(jù)。

Juno Agent 生成的 Target 配置如下:
- targets:
- "127.0.0.1:9999"
labels:
instance: monitor-demo
job: jupiter
如果需要增加其他的監(jiān)控數(shù)據(jù),可以不使用 Juno Agent,直接在 Prometheus 中增加期望的 Pushgateway,并且在 Juno Admin 中的 Grafana 配置管理中直接增加模板地址即可進(jìn)行嵌入展示。以下按照我們使用的監(jiān)控數(shù)據(jù)上報格式舉例,Jupiter Client 會將服務(wù)啟動時相關(guān)的:應(yīng)用版本、機(jī)器 IP、機(jī)器名稱、應(yīng)用信息寫入 buid_info 中,這些基礎(chǔ)數(shù)據(jù)會作為其他監(jiān)控直接的基礎(chǔ) label,進(jìn)行后續(xù)的監(jiān)控條件篩選。
kubernetes 集群部署方案
虛擬容器化是大勢所趨,Juno 監(jiān)控中心對 k8s 集群的支持方案基本與物理機(jī)部署方案一致,容器會產(chǎn)生 Pushgateway 地址漂移,從管理后臺通過 UI 界面查詢需要根據(jù)歷史 POD 數(shù)據(jù)進(jìn)行歷史監(jiān)控數(shù)據(jù)查詢。
多機(jī)房部署方案設(shè)計
Juno 監(jiān)控中心支持多機(jī)房(IDC),在實(shí)際業(yè)務(wù)場景中會同時使用多地區(qū)的機(jī)房,機(jī)房之間不進(jìn)行跨機(jī)房通信,
每個機(jī)房都搭建獨(dú)立的 ETCD 和 Prometheus,監(jiān)控數(shù)據(jù)在各機(jī)房進(jìn)行獨(dú)立存儲,管理后臺(Juno Admin)通過內(nèi)嵌 Grafana 訪問各機(jī)房 Prometheus。所有的數(shù)據(jù)流轉(zhuǎn)由某一個部署監(jiān)控中心管理后臺的機(jī)房完成,該機(jī)房依靠專線與其他機(jī)房進(jìn)行通信,在遭遇專線網(wǎng)絡(luò)故障時,可直接切換到外網(wǎng) IP 保證服務(wù)穩(wěn)定,對不同機(jī)房間的操作互相隔離,不產(chǎn)生依賴影響。
!

技術(shù)點(diǎn)詳解
監(jiān)控數(shù)據(jù)采集實(shí)現(xiàn)
部署基礎(chǔ)服務(wù)包括 ETCD 和 Prometheus;
采用 Jupiter 框架構(gòu)建服務(wù),成功啟動服務(wù)后會完成兩個操作:
寫入監(jiān)控 key-value;
通過服務(wù)治理端口提供 Pushgateway;
在 Prometheus 部署的機(jī)器上,進(jìn)行 Juno Agent 服務(wù)部署完成兩個功能:
進(jìn)行 ETCD 的監(jiān)控 key-value 監(jiān)聽;
通過監(jiān)聽的數(shù)據(jù)產(chǎn)生 Prometheus 需要的 Target 配置;
在 Prometheus 配置生成完畢后,直接拉取 Jupiter Client 的 Pushgateway 數(shù)據(jù),完成監(jiān)控數(shù)據(jù)的采集。
?
監(jiān)控采集時序圖
配置的整個生命周期流轉(zhuǎn)如下圖所示,歸納為四個配置點(diǎn)進(jìn)行表述:管理后臺(前端交互 UI)、配置服務(wù)(管理后臺服務(wù))、下發(fā)服務(wù)(Minerva Proxy+Minerva Agent)、應(yīng)用。

網(wǎng)關(guān)功能
采用 Grafana 子域名配置,直接使用 Juno Admin 的域名例如(http://jupiterconsole.douyu.com/),配置為(http://jupiterconsole.douyu.com/grafana)直接進(jìn)行訪問,采用 juno 系統(tǒng)的登錄態(tài)以及用戶信息,統(tǒng)一了用戶權(quán)限管理。
!

目前網(wǎng)關(guān)功能在后期可擴(kuò)展成對任意無狀態(tài)的三方系統(tǒng)的鑒權(quán)支持,只需要在 Juno Admin 網(wǎng)關(guān)設(shè)置中進(jìn)行域名以及目標(biāo)地址的配置即可。
可用性分析
分析多故障場景,當(dāng)前 Juno 監(jiān)控中心的降級方案如下:
| 場景 | 影響 | 降級方案 |
|---|---|---|
| Juno Agent 掛掉 | 新增服務(wù)無法生成對應(yīng)的 Prometheus Target 配置,拉取不到監(jiān)控數(shù)據(jù)。不影響已有服務(wù)的監(jiān)控采集與查詢 | |
| 某個 ETCD 節(jié)點(diǎn)掛掉 | 無影響 | Juno Agent 可以重連其他 ETCD 節(jié)點(diǎn) |
| 全部 ETCD 節(jié)點(diǎn)掛掉 | Jupiter Client 啟動后無法成功寫入監(jiān)控 Key,同樣無法生成 Target 配置。不影響已有服務(wù)的監(jiān)控采集與查詢 | |
| Prometheus 掛掉 | 無法采集監(jiān)控數(shù)據(jù) | |
| Grafana 掛掉 | 無法查詢監(jiān)控數(shù)據(jù) | |
| 專線故障 | 監(jiān)控數(shù)據(jù)拉取失敗 | 使用公網(wǎng) IP 繼續(xù)相關(guān)操作 |
為什么選擇 ETCD
為什么采用 ETCD 作為監(jiān)控中心和配置存儲/訂閱通知引擎,而不是使用傳統(tǒng)的 ZK,Eureka?我們大致總結(jié)了一下,有以下幾方面的原因:
它提供了強(qiáng)大和靈活的 K-V 存儲能力,可以在保證性能的前提下對配置項(xiàng)進(jìn)行最小粒度對存儲;
它提供了對 key 或者 key 前綴的監(jiān)聽功能,正好滿足我們對某些配置項(xiàng)需要動態(tài)下發(fā)的需求;
我們的項(xiàng)目本身就使用了 ETCD 做服務(wù)注冊與發(fā)現(xiàn)和存儲功能,維護(hù)和使用相對于 zk,Eureka 會熟練的多。
為什么采用 Prometheus
為什么監(jiān)控中心采用 Prometheus 進(jìn)行監(jiān)控指標(biāo)存儲,有以下幾個原因:
Prometheus 是 CNCF 旗下成熟的開源項(xiàng)目,社區(qū)活躍;
數(shù)據(jù)模型靈活,多樣性的 label,在數(shù)據(jù)采集階段支持?jǐn)?shù)據(jù)屬性自定義;
PromQL,強(qiáng)大的查詢能力,多功能封裝的查詢語句,能滿足絕大多數(shù)業(yè)務(wù)場景;
良好的性能,支持每秒十萬條以上的監(jiān)控數(shù)據(jù)采集。
交互設(shè)計
界面概覽
下圖是 Juno 監(jiān)控中心的首頁。

頁面上方:
應(yīng)用選擇以及環(huán)境切換,展示了應(yīng)用相關(guān)的基礎(chǔ)信息;
機(jī)房切換;
應(yīng)用服務(wù)可用功能模塊切換;
頁面中央,采用按鈕形式展示了可用 Dashboard;
頁面下方,嵌入 Grafana 監(jiān)控頁面。
?
服務(wù)概覽
服務(wù)概覽有三個側(cè)重點(diǎn):響應(yīng)時間、QPS、成功率。這是對服務(wù)整體質(zhì)量的評價。

健康檢查
目前服務(wù)在某一環(huán)境中部署的實(shí)例數(shù)量,是否存在異常情況,最大的文件句柄數(shù)、CPU 消耗、內(nèi)存使用、QPS 指標(biāo),能幫助用戶在第一時間了解的當(dāng)前服務(wù)的具體情況,進(jìn)一步服務(wù)心跳更新時間,當(dāng)前采用的框架版本相關(guān)的 git 提交版本,都進(jìn)行表格化展示,可以為問題排查提供更多的客觀數(shù)據(jù)。

實(shí)例監(jiān)控
從實(shí)例維度進(jìn)行服務(wù)監(jiān)控分析。

服務(wù)端監(jiān)控
服務(wù)本身對外提供服務(wù)的情況,依據(jù) HTTP 和 GRPC 進(jìn)行區(qū)分,給出 QPS 和 P99 的數(shù)據(jù)。

接口監(jiān)控
對服務(wù)提供的具體 API 進(jìn)行監(jiān)控指標(biāo)采集和展示。

客戶端監(jiān)控
查詢當(dāng)前服務(wù)對下游服務(wù)的調(diào)用情況監(jiān)控,可以快速定位是服務(wù)本身異常,還是下游服務(wù)異常。

容器監(jiān)控
服務(wù)容器化部署之后,給出對 pod 情況的獨(dú)立監(jiān)控,可結(jié)合服務(wù)本身監(jiān)控進(jìn)行交集查詢。

模板配置
提供模板配置的功能,用戶可以自行修改 Dashboard 地址,系統(tǒng)會依次展示這些 Dashboard。

總結(jié)
本文從 Juno 監(jiān)控中心的層次結(jié)構(gòu)開始分析,說明了服務(wù)監(jiān)控采集流程包括客戶端、服務(wù)端的設(shè)計,講解了部分技術(shù)點(diǎn)包括采集時序圖、網(wǎng)關(guān)設(shè)計等;在架構(gòu)分析的基礎(chǔ)上對各個功能點(diǎn)進(jìn)行分析,希望幫助各位進(jìn)一步理解我們的設(shè)計思維;最后展示監(jiān)控相關(guān)的交互頁面,以及斗魚 Juno 監(jiān)控中心設(shè)計的監(jiān)控系統(tǒng)設(shè)置界面。
相關(guān)資料
jupiter 官網(wǎng)?http://jupiter.douyu.com
jupiter 倉庫地址
https://github.com/douyu/jupiter
juno 倉庫地址?
https://github.com/douyu/juno
demo 演示地址?
http://jupiterconsole.douyu.com
?
