一. 摘要
本文內容分為3部分,首先簡單介紹了美圖的業務背景和監控體系,然后是兩個美圖的監控實踐----基於Grafana FlowCharting插件的「監控大盤」實戰和基於基於GrafanaImageRender+企業微信機器人的「圖文告警」實戰。這兩個監控實戰都是非常容易落地的,基本是開箱即用,中間只涉及到非常少量的代碼工作。本文除了介紹我們做相關技術選型時的一些考量,同時給出了兩個實戰完整的“step by step”的操作步驟,對於涉及到的少量代碼工作,文中也給出了代碼樣例。希望這兩個案例對於大家做監控大盤和富文本告警的工作可以有所參考。
二. 美圖監控的整體架構
1. 業務背景
在展開技術實戰部分的講解之前,我們先簡單了解下美圖公司的業務場景和規模。美圖公司的業務主要分為 ToC 和 ToB 兩類,以「消費者社區」為核心,在「影像美化」、「美妝平台」、「皮膚管理」幾個垂直領域均有面向終端用戶和面向企業的產品或解決方案。
美圖的產品線覆蓋社區、美顏、美妝、短視頻、直播等領域,比較知名的C端APP有美圖秀秀、美顏相機、美妝相機、美拍等。此外,美圖擁有大量的海外用戶,知名的產品有 BeautyPlus、AirBrush 等。圍繞這些 APP 同時建設有大量的支撐服務,比如基礎架構、大數據、AI開放平台、商業化生態等。
美圖的產品線眾多、業務形態豐富、ToC和ToB的服務並存,如何保障眾多線上服務的穩定性也就是眾多技術同學尤其是SRE同學所面臨的挑戰。而要保障服務的穩定性,不可或缺的一點就是對服務質量的感知力,也就要求我們建設一套穩定、高效、契合業務的監控系統。美圖的監控體系就是建立在前文的場景和規模之下的,下面讓我們來深入了解一下。
2. 監控體系
美圖的整個監控體系分為「用戶端」和「服務端」兩大塊。
-
「用戶端」主要覆蓋客戶端和中間鏈路。目前主要基於美圖自研的APM(內部代號哈勃)來做客戶端的的質量監測,監控的指標有:網絡質量、崩潰、卡頓、響應時間、錯誤率、慢請求等。除此之外,美圖還建設有流媒體的監控體系,主要用來覆蓋直播推流拉流、點播拉流、CDN質量等。
-
「服務端」的部分涵蓋的內容比較多,如果從業務的請求鏈路來看,服務端的監控會覆蓋從「入口層負載均衡」到「業務服務」、到「周邊依賴服務」的調用、到「后端資源類服務」等整個請求鏈路。此外,還有一些基礎設施的監控。
因為目前美圖的業務已經“全量上雲”,我們對基礎設施的監控就不再過多關注網絡設備、服務器等物理硬件相關的內容了,更多地轉向了對雲上基礎設施的監控,比如網絡質量、ECS虛機、容器平台、DNS等基礎服務等。
美圖整體的監控體系可以參照上圖,本圖的繪制時間稍微有點早了,但是基本的信息都還是適用的。
美圖是從2016年開始推進完善上述監控體系的,在這個過程中我們也調研、測試、引入了眾多的技術工具和技術棧:
-
Zabbix、OpenFalcon、OpenTSDB 基礎監控
-
ELKB 日志套件
-
InfluxDB 的 TICK 套件
-
Prometheus
-
Spark、Storm、Kafka、Flink 等大數據套件
-
Netdata、Sentry、EagleEye、SkyWalking 等
此外,美圖也基於開源的組件做了大量的二次開發的工作,同時也建設了一些諸如通知系統 NoticeSystem、統一告警平台 MTAlert 等工具。
監控體系涉及的內容比較龐雜,無法在一篇文章中做到全面細致的講解,下面會將更多的篇幅放在「全鏈路監控報表」的建設思路上,並且會附帶一個監控大盤和告警的實戰。
3. 監控大盤
a. 統一監控報表查看入口到Grafana
經過上述的建設,已有的監控工具已經可以較好的覆蓋從客戶端到服務端的各個環節了,這時卻有了新的問題:監控系統太多、報表散落在各個系統,業務方排查一個問題可能需要在多個系統之間來回切換,體驗非常不好。
這時候我們希望有一個統一的用戶界面來展示不同監控系統的數據,我們也做了一些簡單的調研。當時我們調研的方案有:自建前端、用iframe簡易嵌套組合、Grafana。
自建前端和iframe嵌套的優點都是可以接入更多的監控系統,但是缺點也都比較明顯。自建前端是可定制化程度最高的方案,但是需要比較多的適配工作,隨着各個監控系統的迭代,平台維護的工作量也是比較可觀的;iframe嵌套的方式倒是簡單粗暴,但是並沒有從本質上解決數據割裂的問題,並且還需要解決不同監控平台之間的用戶權限打通的問題。
最終我們選擇了Grafana作為統一的監控Dashboard工具,當時考量的點主要有:
-
Grafana對我們當時在用的大部分監控系統(數據源)都有支持,比如Zabbix、OpenTSDB、Prometheus、InfluxDB、Elasticsearch
-
Grafana是Prometheus官方推薦的展示組件,當時我們已經在大量推進業務側的Prometheus監控,這個點對我們的決策比較重要
-
Grafana的發展很迅猛,社區活躍,有“大一統”之勢
於是把原先沒有接入到 Grafana 的數據源做了統一的接入,用 Grafana 來提供統一的監控用戶界面。
當然,Grafana也有一些問題,比如對一些數據源沒有提供支持或者支持不夠完美,日志、告警的能力比較弱(現在已經有非常大的改觀)等。對於這些問題,我們選擇容忍或使用其他方案來配合和覆蓋,比如:
-
ELK技術棧中的日志細節查看還是需要借助Kibana,Grafana則更合適去呈現Elasticsearch的匯總數據或變化趨勢
-
Prometheus的PromQL的調試、AlertManager的管理,可能還是原生的UI會更友好
-
監控告警的需求,我們則更多的依賴我們的告警平台MTAlert來做覆蓋
考慮到我們的原始需求(統一的監控UI),目前Grafana是可以滿足我們絕大多數日常的監控可視化需求的。
b. 在一張報表(Dashboard)中展示業務鏈路
在用 Grafana 解決了數據源散落在多個系統的問題之后,業務方可以不用頻繁的在多個監控系統之間做切換了。但是由於請求鏈路中不同階段的監控圖表還是存放在不同位置的,業務方在實際的使用中還是需要在多個Org、Dashboard 或 Panel 中切換。
比如上文提到的典型的請求鏈路:
業務方期望能有一個全局的視角,可以在一個頁面或者圖表中體現出這些環節的監控數據,這時候我們可以怎么做呢?
通常的思路就是我們在一張 Dashboard 中,以業務的維度建立不同層次的 Panel,把這個業務相關的各個環節的監控圖放到一起,這樣業務方在一個頁面里去做點擊和滾動就可以了,相比前面的方式我們又往前邁了一步。
比如下面的兩個樣例:
Tips:在監控數據、業務線、用戶數量比較多的時候,建立一套Grafana的使用規范(共識)是非常有必要的,這套規范可能需要涵蓋:
Grafana中各種資源的申請和使用約束
數據源的管理規范
權限管理規范
Org、報表命名規范
c. 我們還可以更進一步嗎?
回顧一下上面兩個階段中監控報表的發展:
-
從監控數據散落在多個系統中,到把匯總數據到同一個平台(Grafana)
-
再到把不同Org、不同 Dashboard 中的數據匯總到一張 Dashboard 中展示
這個發展路徑中,我們都是在試圖把(相關聯的)監控數據匯總到一個地方,整體的方向是越來越集中的。因為我們的一個訴求是期望可以在更少的頁面中去看到更多的信息,以此來輔助我們更好地掌控服務、更快地排查問題。
但其實,上面的這些方式都只是解決了“監控數據集中展示”的問題,我們還有一個更核心的訴求之前是一直沒有得到滿足的:我們希望看到各個監控數據之間的關聯關系。我們希望可以通過各層次、各依賴服務、各資源的監控狀態,以及它們之間的關聯關系,來輔助業務方構建一個更立體的全局視角。比如現在服務SLA告警了,我希望一眼看到整個系統中所有關聯模塊的狀態,希望能夠知道這個SLA問題(告警)可能是由什么導致的。如果監控系統可以達到這個目標的話,它就可以輔助業務方打造一個全方位的服務感知能力,也可以讓問題排查和定位變得更高效。
這個需求類似於「服務鏈路跟蹤」或者「根因定位」,但是這兩個領域都是需要大量基礎建設和業務適配的,工作量大,推行成本比較高。那我們有沒有什么折中的方案,是可以“以較小的代價”來實現(或者部分實現)這個需求呢?接下來,讓我們看一下目前在美圖推廣的一個基於 Grafana FlowCharting插件的監控大盤實踐,看下這個是否可以給你帶來一些參考。
三. 基於FlowCharting的監控大盤實戰
1. FlowChating介紹
FlowCharting是一款Grafana的插件從名字應該就可以大概了解這款插件的用途。flow,流、數據流;charting,圖表。這個插件是基於draw.io在線繪圖庫的,用draw.io可以完成非常復雜的圖表的繪制,比如網絡拓撲圖、數據流量圖、技術架構圖等,然后我們可以用FlowCharting為圖表中的各個元素綁定動態的數據,從而完成一張動態的圖表。
我們借助這個插件完成了“把服務整個請求鏈路的監控數據匯總到一張圖表”的需求,通過這樣的圖表我們可以一眼看到服務當前狀態的全貌。如下圖所示,我們把一個服務從「客戶端」到「服務端」以及「依賴服務」和「資源服務」的監控數據都匯總到了一起。通過為不同的監控數據設置不同的閥值、配置不同的顏色,可以更直觀的看到整個系統的健康狀態。
這個方案里各個監控數據之間的邏輯關聯性可能不像trace系統中那么緊密,需要人工去梳理服務的監控項、繪制可以體現數據鏈路及邏輯關系的圖標,但是它切實解決了之前我們監控數據邏輯性不夠直觀的問題。當系統出現問題的時候,我們可以快速的從這張圖表中看到各層、各組件及組件之間的鏈路狀態,它切實提高了我們在問題排查中的效率。
對於這個方案的另一點說明:這個插件只是提供了一種數據可視化的方法,前提還是需要先建設有相關的監控數據。如果你面臨的場景跟我們是類似的----已經有各類監控數據,但是苦於如何更直觀地把監控數據展示出來,那么這款插件一定值得嘗試。
2. 監控大盤實踐Step by Step
a. 第一步:繪制圖形
首先,我們需要借助 draw.io 來繪制我們的業務架構圖(如圖-業務架構圖)。
業務架構圖
流程圖繪制工具可采用以下兩種方式:
-
Web在線繪制:draw.io
-
本地客戶端繪制:客戶端下載地址
業務架構圖繪制完畢后,我們通過點擊【其他】-【編輯繪圖】可以看到圖形的代碼。
b. 第二步:將圖導入Grafana
我們先將 draw.io 中的流程圖代碼粘貼在 Source Centent 中,粘貼完畢后,我們就可以從 Grafana 看板中看到繪制好的圖形了。
-
Edit Draw:在線編輯當前圖形。
-
Prettify:格式化圖形代碼。
-
Minify:合並圖形代碼。
-
Compress/Encode:加密圖形代碼。
-
Extract/Decode:解碼圖形代碼。
生成好繪制的圖形后,我們就可以開始調整看板的基礎配置。
-
Bg Color: 可以調整 grafana 看板背景色。
-
Enable animation:開啟動畫效果。
前提條件:Grafana需要安裝並開啟FlowCharting插件。詳見:https://grafana.com/grafana/plugins/agenty-flowcharting-panel/installation
c. 第三步:為圖形元素綁定監控數據源
我們需要為關鍵圖形元素添加監控數據源。根據需求可以在報表中添加相應的 Query 語句。
此處各個查詢語句的"名稱",會用於下文中關聯圖形使用。
d. 第四步:配置圖形展示規則
在報表中可以通過添加 Rule ,來設置我們圖形的展示效果。
如上圖所示,Options 是用來關聯上一步中添加的監控數據源。
-
Rule name: 規則名稱。
-
Apply to metrics:與哪個查詢語句關聯 (支持正則)。
-
Aggregation: 為數據源選擇一個聚合。
Type 是用來設置數據源展示的指定單位和類型。
-
Type:類型。
-
Unit:單位。
-
Decimals:保留幾位小數。
Thresholds 用來設置圖形展示的顏色變化規則。
-
Invert:倒序排列。
-
Gradient:使用漸變顏色。
-
Icon state:圖標狀態。
Tooltips 開啟后,將鼠標移動到具體圖形上,會自動展示對應監控值一個周期狀態,
如下圖所示。
-
Label:彈出窗口中展示的標簽(默認和查詢語句命名的"名稱"相同)。
-
Direction:垂直顯示還是水平顯示。
-
Color with state:彈出的圖形顏色是否和服務狀態顏色保持一致。
Graph Tooltips 用來設置彈出圖形展示的效果。
-
Graph type:使用線性或者柱狀圖。
-
Graph Size:彈出的圖形大小。
-
Scale type:顏色填充部分選擇。
e. 第五步:關聯具體的圖形
我們將具體的圖形關聯到配置好的 Rule 中,這樣就可以在 Grafana 看板中看到具體圖形的狀態顏色了。
Color/Tooltip Mappings 顏色映射,圖表顏色填充/邊框填充等。
-
Identify by:選擇一種圖形的關聯類型,有 id 和 Label 兩種。
-
id:即每個圖形的 id。例如流程圖代碼中的 UD0VAbfAxGPwaQMbtyaW-13
-
Label:即每個圖形的"標題"。例如流程圖代碼中的 value 值 MTXX
-
Regular exression:是否使用正則。如果下方 What 中的值未使用正則,請關閉這個開關以提高性能。
-
Buttons:選項的添加和刪除。
-
What:與哪個圖形關聯,添加圖形關聯的方式有兩種:
-
手動填寫"圖形id"或"圖形標題"。
-
先點擊 Buttons 中的鏈接標志,再點擊圖形,會自動讀取 Pannel 中的"圖形id"或"標題"。
-
When:顏色填充觸發條件。
-
How:填充類型。
Label/Text Mappings: 數值映射, 圖表與查詢結果的數值填充。
-
When:數值顯示條件。
-
How:數值顯示位置。
Link Mappings: 鏈接映射,點擊圖形可跳轉至指定 URL(比如具體監控項的詳情頁面)。
Event/Animation Mappings: 事件映射。
f. 第六步:完善流程圖中其他圖形
最后,為所有需要監控的圖形創建對應的 Rule ,整個業務流程監控大盤就制作完畢了。至此,你將收獲一張包含動態監控數據的監控大盤。
四. 基於GrafanaImageRender+企業微信的「圖文告警」實戰
1. 思路介紹
這個部分可以算作是上一個實戰的延展,經過上面的建設我們已經有了服務級整體的請求流向圖后。如果我們可以在服務發生「告警」的時候,同時把「監控大盤」的信息發出來,讓我們在收到服務告警的同時可以快速感知服務的整體狀態,這將大大提升我們問題排查的效率。
結合目前我們在用的企業IM的群機器人告警通道和Grafana的ImageRender,告警和監控大盤的聯動也就水到渠成了。目前美圖選用的企業IM是企業微信,我們只需要在服務告警發生的時候,同時將監控大盤的「狀態截圖」通過企業微信的IM機器人發到各個群組即可。
釘釘、飛書等企業IM也都有提供群機器人的功能。
結合美圖已有的監控告警組件,我們選擇的告警發送請求鏈路為 Grafana-Image <-> MTAlert -> 企業微信機器人。
組件說明
MTAlert為美圖自研告警平台,支持配置監控告警。同時支持在觸發指定監控告警時,將告警的內容發送給擴展腳本做定制處理。
GrafanaImageRender是Grafana的一個后端插件,用這個插件可以把Panel或者Dashboard渲染為PNG圖片,官方建議獨立部署。
告警流程 我們的告警規則是維護在MTAlert中的,當告警發生的時候我們將告警消息發給一個指定的腳本。這個腳本負責根據約定好的規則做過濾和處理,去GrafanaImageRender渲染圖片並獲取圖片的鏈接,然后將組合后的圖文消息發送給指定的企業微信群機器人。
用這樣的方式,我們就可以在一條告警消息中獲取到服務本身及上下游的即時狀態,從而讓我們對問題的原因和影響范圍有一個快速的大致判斷,進而縮短問題排查時間,降低MTTR(故障平均修復時間),提升服務的穩定性。
2.「圖文告警」實戰Step by Step
a. 第一步:創建群機器人並獲取 Webhook
> [企業微信 - 如何使用群機器人](https://work.weixin.qq.com/help?doc_id=13376)
因告警會包含圖片和標題, 使用圖文類型消息, 需要發送給 Webhook 的格式如下:
PS: 機器人的頻率限制為每個機器人發送的消息不能超過20條/分鍾。
b. 第二步:獲取 Grafana-Panel 圖形鏈接
-
獲取流向圖所在 Grafana-org 的 API Keys。
可指定 Keys 的有效時長, 如果不指定, 則 key 永久有效。
-
獲取指定 Panel 的渲染圖形鏈接。點擊指定 Panel 的 Share 后, 可以看到 Direct link rendered image。
-
使用 Grafana-Image 根據渲染圖形鏈接獲取該 Panel 的 png 格式的圖形鏈接。
curl -H "Accept: application/json"
-H "Authorization: grafana_api_key"
-d '{"imageUrl":"http://grafana-panel-url/render/d-solo/panelxxxxx"}'
"http://grafana-images-server/grafana-images"
調用成功可得到如下的返回值
{"pubImg":"http://grafana-images-server/f6cdd1xxxxxxxb01b.png"}
我們的GrafanaImageRender為獨立部署的模式,通過HTTP方式提供服務。傳入一個GrafanaPanel的URL(還有Grafana的API Key)將得到一個可以直接訪問(公網下或者受信網絡下)的圖形的URL。
c. 第三步:配置監控告警策略
-
自研 MTAlert 添加監控策略。此處的 Grafana 鏈接為 渲染圖形鏈接(非 png 格式圖形鏈接),且該內容會在觸發告警時作告警內容的一部分被發送給下游。
為提升擴展腳本的可擴展性, 我們對告警配置中的grafana鏈接約定了一個固定的格式:grafana鏈接&&&&&&微信機器人webhook地址&&&&&&報警名稱&&&&&&報警描述&&&&&&
-
添加告警擴展, 與監控策略聯動。如果使用了告警擴展, 在觸發告警后, 告警平台會將告警內容傳送對應的擴展腳本。告警擴展對於過濾類型,需要腳本返回 ture OR false。告警平台如果收到 true 的返回,將認為告警需要發出,如果收到 false,則不會發出該告警。
d. 第四步:告警擴展腳本
告警擴展腳本我們使用了Python,告警擴展會固定調用腳本中的 getExtendData(data) 這個函數,其中 data 為告警平台傳送的告警內容。擴展腳本部分代碼如下:
# 3. 發送告警
def SendPanelMsg(token, new_panel_url, webhook_url, title, description):
public_url = GeneratePanelPngurl(token, new_panel_url)
data = {
"msgtype": "news",
"news": {
"articles": [
{
"title": title,
"description": description,
"url": public_url,
"picurl": public_url
}
]
}
}
# post
url = webhook_url
postdata = json.dumps(data)
request = urllib2.Request(url, postdata)
request.add_header('Content-Type','application/json')
try:
response = urllib2.urlopen(request)
return 'post Success'
except Exception as ex:
return 'post Exception'
def getExtendData(data):
# 1. 從告警內容中獲取該條告警策略對應的信息: 渲染圖形鏈接, 機器人 webhook, 告警策略名稱, 告警策略描述;
msg_info = json.loads(data)
msg_data = msg_info['data']
msg = msg_data['報表地址'.decode('utf-8')]
msgArr = re.split('&&&&&&', msg)
if len(msgArr) != 5 :
print 'mtalert->業務預警配置->grafana鏈接 配置有誤!格式應為: grafana_panel_url&&&&&&webhook_addr&&&&&&alert_title&&&&&&alert_description&&&&&&'
return 'true'
panel_url = msgArr[0]
webhook_url = msgArr[1]
title = msgArr[2]
description = msgArr[3]
# 2. 獲取對應 org 的 Token, 修改渲染圖形鏈接時間范圍為當前時間, 生成新的渲染圖形鏈接.
org_id = GetOrgId(panel_url)
token = GetOrgToken(org_id)
panel_time_range = 30
new_panel_url = GenerateNewPanelUrl(panel_url, panel_time_range)
# 3. 由渲染圖形鏈接請求 Grafana-Image, 獲取 png 格式圖形鏈接, 並通過群機器人 webhook 發送帶圖形的告警.
SendPanelMsg(token, new_panel_url, webhook_url, title, description)
return 'false'
e. 告警實例
以上就是這個實戰的全部內容了,其實整個實踐的思路還是比較簡單和清晰的,大家可以根據自己的環境做些靈活的適配。
五. 未來展望
基於FlowCharting的大盤實踐和信息更豐富的圖文告警,相比於傳統的監控和告警方式來講,雖然略新穎,但是基本都還是圍繞“工具應用”的層面開展的。這遠不是終點,我們還有非常多的事情需要繼續去推進,下面是兩個較為“清晰”的思路或方向,大家或許可以參考:
一、我們需要有一個認識 ---- “監控只是幫助我們達成某些目標的工具或手段,而不是最終的目的”。因此我們還可以繼續往前邁進,做更多的橫向連接和擴展。比如:
-
如果我們的目標是「服務的穩定性」,我們可以跟服務的彈性策略、異常處理、故障自愈做聯動,更好地做服務質量保障。
-
如果我們的目標是「降低成本」,我們的監控數據也可以提供強有力的支撐,配合對監控數據的挖掘,指導我們更好的做容量規划。
二、再有一個較為前沿,也正在如火如荼開展的方向則是「基於DataOps/AIOps的(監控)實踐」。通過大數據、機器學習等新興技術手段,更好的挖掘監控數據的價值,打造更智能的工具體系,用更科學、更智能的方法來輔助運營和生產。
當然,未來在監控上可以做的事情也遠不止這些,我們可以一同努力、共同期待。
六. 全文總結
本文先介紹了美圖的監控體系,然后着重講解了監控大盤的發展:按照將監控數據盡可能集中匯總的思路,我們逐步把監控數據從多個系統收斂到一個系統,然后我們把多個監控報表整合到一個頁面中進行呈現,最后我們用FlowCharting這個插件把監控數據的集中展示做到了“極致”,在一張圖表中展示。同時巧用FlowCharting插件來體現監控數據之間的關聯關系,由此我們就可以用它以較低的成本構建出一個「端到端的全鏈路監控」了。
最后,我們分享的一個基於GrafanaImageRender組件和企業微信群機器人的“圖文告警”實戰。
PS:目前這套監控大盤和圖文告警在美圖的應用效果非常不錯,感興趣的同學也可以做一些嘗試。
文章作者介紹: 石鵬、朱起飛、王苑卜,三人均為美圖產品SRE團隊的同學。
鳴謝:感謝公司所有參與基礎設施、監控平台建設的同學,感謝各兄弟部門在上述建設中提供的協助和支持。