可視化大屏:從指標(biāo)口徑到實時鏈路實踐)
作為一個常年跟分布式執(zhí)行鏈路打交道的人我對“監(jiān)控大屏”這件事態(tài)度一直很矛盾做淺了就是接幾個圖表把數(shù)據(jù)畫出來老板看一眼就不看了做深了又容易陷進具體的組件細(xì)節(jié)里壓根看不到整體。但 Harness 層的 Agent 運行狀態(tài)可視化不一樣它是那種“不做不知道做了才覺得真該早做”的基礎(chǔ)工程。這里說的 Harness 層你可以把它理解成任務(wù)調(diào)度和 Agent 執(zhí)行之間的“中間管理層”負(fù)責(zé)統(tǒng)一管理海量 Agent 的生命周期、承接指令下發(fā)、收集執(zhí)行結(jié)果。沒有這層透明化Agent 到底在干嘛、卡在哪、有沒有在空轉(zhuǎn)全憑猜。我在實際經(jīng)歷里最大的體會就是這類監(jiān)控大屏核心不是那張大屏而是“運行狀態(tài)可視化的數(shù)據(jù)模型怎么建立”。所以這篇不是講三個大屏模板怎么套用而是從 Harness 層的架構(gòu)邊界、指標(biāo)口徑、數(shù)據(jù)采集鏈路到前端 WebSocket 推送、狀態(tài)漂移的排查把整條思路完整還原一遍。如果你正在做類似的基礎(chǔ)設(shè)施可視化項目或者剛接手 Agent 穩(wěn)定性治理但覺得無從下手這篇應(yīng)該能給你省下不少彎路。1. 項目背景與整體設(shè)計先把監(jiān)控邊界畫清楚1.1 數(shù)據(jù)分層與 Harness 層到底扮演什么角色任何監(jiān)控大屏項目第一步絕對不是選圖表框架而是先弄清楚你要服務(wù)的是哪一層數(shù)據(jù)。一個常見的分布式任務(wù)系統(tǒng)大概可以分成三個層面應(yīng)用服務(wù)層面向用戶的功能比如提交任務(wù)、查看結(jié)果。Harness/調(diào)度管理層負(fù)責(zé)把任務(wù)翻譯成 Agent 可執(zhí)行的指令管理 Agent 注冊、健康檢查、升級、負(fù)載分配。它更像是“監(jiān)工”不直接搬磚但每一塊磚運沒運到、由誰運的它最清楚。Agent 執(zhí)行層真正跑在服務(wù)器上的底層執(zhí)行器執(zhí)行命令、跑模型推理、寫文件、上報狀態(tài)。我們做的 Harness 層監(jiān)控大屏服務(wù)的正是中間這層。當(dāng)時有同事建議把監(jiān)控范圍擴大到整條業(yè)務(wù)鏈路被我們攔住了。如果從頁面按鈕一路畫到服務(wù)器 CPU看板必然臃腫最后什么都看不清。既然標(biāo)題寫的是“Harness 層”那最佳口徑就是把 Agent 狀態(tài)、指令分發(fā)情況、Agent 集群健康度作為主體上層業(yè)務(wù)只展示吞吐趨勢底層硬件只留幾個應(yīng)急參考指標(biāo)。1.2 項目真正的目標(biāo)復(fù)現(xiàn)“異常瞬間”而不只是畫圖還有一個設(shè)計層面的問題值得講清楚監(jiān)控大屏和報警平臺有什么不同報警平臺是在出問題時喊你監(jiān)控大屏則是讓你平時就能感知系統(tǒng)正在發(fā)生什么。但更核心的一個目標(biāo)是當(dāng)某類異常出現(xiàn)能通過大屏快速還原出事那一刻的狀態(tài)。比如之前有一次 Agent 批量失聯(lián)當(dāng)時如果只看日志只能知道一條條超時記錄。但大屏上一定要能讓我們一眼看出失聯(lián)是有時間先后順序的還是同時消失的分布在哪些機器上失聯(lián)前是不是有過大批指令下發(fā)。這種按時間軸回放的 Agent 運行狀態(tài)可視化才是大屏項目真正值錢的地方。如果做成純“當(dāng)前在線數(shù)”那種儀表盤就沒有這個復(fù)現(xiàn)現(xiàn)場的能力了。2. 指標(biāo)體系建設(shè)最容易返工卻最沒人重視的環(huán)節(jié)2.1 核心指標(biāo)到底要選哪些為什么是這些確定了大屏邊界后最先要做的是指標(biāo)清單而不是先畫原型。Harness 層最關(guān)鍵的 Agent 運行狀態(tài)指標(biāo)我按照自己踩過坑后的經(jīng)驗分成四組生命周期類注冊 Agent 數(shù)、在線 Agent 數(shù)、離線 Agent 數(shù)、啟動中 Agent 數(shù)。用來判斷整個集群的真實規(guī)模。心跳與連接類心跳上報成功率、平均心跳延遲、最近心跳分布。這兩個指標(biāo)能快速區(qū)分網(wǎng)絡(luò)抖動和 Agent 進程假死。任務(wù)執(zhí)行類排隊中任務(wù)數(shù)、執(zhí)行中任務(wù)數(shù)、任務(wù)成功率、平均執(zhí)行時長。資源與異常類CPU/內(nèi)存均值、指令超時次數(shù)、異常退出次數(shù)、Agent 版本分布。我們在第一期只做了前三組結(jié)果上線后發(fā)現(xiàn)少了一個關(guān)鍵視角版本分布。有一次新版本 Agent 灰度引入內(nèi)存泄漏老版本都正常新版高負(fù)載時不穩(wěn)定。沒有版本維度的大屏只會看到“某區(qū)域 Agent 在線率下跌”排查很久才定位到是版本問題。所以版本分布這事后期又被塞進了大屏的輔助區(qū)域雖然不大但真的救命。2.2 指標(biāo)的采集口徑一個半小時的返工教訓(xùn)指標(biāo)定下來之后更大的坑在于采集口徑。我們當(dāng)時因為多套系統(tǒng)之間的定義不統(tǒng)一吃過很大的虧。具體來說任務(wù)成功率有兩種算法一是從 Harness 的數(shù)據(jù)庫里統(tǒng)計指令狀態(tài)為成功的總數(shù)除以總數(shù)二是從每個 Agent 上報的事件日志里統(tǒng)計成功事件數(shù)除以事件總數(shù)。前者偏向最終狀態(tài)后者偏向過程記錄。由于 Agent 重啟或重試的問題這兩個分母并不一樣一度導(dǎo)致大屏的數(shù)據(jù)和明細(xì)后臺對不上。后來我們固定了一條規(guī)則一切以 Harness 層落庫的“任務(wù)狀態(tài)流轉(zhuǎn)記錄”為唯一數(shù)據(jù)源Agent 上報事件僅作為輔助證據(jù)。到這一步我才理解做可視化項目時圖表美術(shù)只是殼指標(biāo)口徑的一致性才是骨架。每個指標(biāo)在畫上去之前必須寫清它的定義公式、采集源、時間窗口。寧可花一天做指標(biāo)字典也別上線后花一周對數(shù)據(jù)。2.3 標(biāo)簽設(shè)計決定了后續(xù)能怎么“切”在設(shè)計存儲和圖表時要預(yù)先考慮好需要從哪些維度篩選。我建議每個 Agent 運行時至少帶上這幾類標(biāo)簽集群/區(qū)域版本號操作系統(tǒng)和架構(gòu)Agent 所在宿主機或 Pod負(fù)責(zé)的業(yè)務(wù)線有了這些標(biāo)簽大屏的數(shù)據(jù)才能被靈活切片。比如你后來想做一個“按業(yè)務(wù)線查看當(dāng)前 Agent 成功率”的視圖就不需要重新改造上報格式只要查詢時按 label 過濾即可。這套思路和 Prometheus 的時間序列模型很像指標(biāo)名 標(biāo)簽集合就是唯一的時間序列標(biāo)識。3. 數(shù)據(jù)鏈路與實時計算從 Agent 上報到大屏渲染3.1 Agent 主動上報和中心拉取到底選哪個到這里指標(biāo)清單有了接下來是數(shù)據(jù)的“運輸問題”。Harness 層和 Agent 之間通常已經(jīng)存在長連接或 HTTP 輪詢。如果是長連接更適合做服務(wù)端推送監(jiān)控如果是短連接可以采集心跳但難以做到精確的在線狀態(tài)。我們的 Agent 選擇的是 MQTT 長連接和 Harness 的 Broker 保持心跳。這樣在線狀態(tài)基本是準(zhǔn)實時的無需再去額外掃描服務(wù)器端口。與之配套的還有一套兜底機制若 MQTT 通道斷開Agent 本地會緩存最近的任務(wù)執(zhí)行日志恢復(fù)后自動重傳。這在實現(xiàn)監(jiān)控時價值很大因為它能解釋“為什么 Agent 顯示在線但數(shù)據(jù)很久沒更新”的情況。另外有個經(jīng)驗大屏上“Agent 在線數(shù)”統(tǒng)計的并不是 MQTT 的連接數(shù)而是最近 5 分鐘內(nèi)有有效心跳的 Agent 個數(shù)。MQTT 連接可能處于半開狀態(tài)連接沒斷但收不到數(shù)據(jù)如果只看連接數(shù)會掩蓋一部分假死問題。這個規(guī)則我們在數(shù)據(jù)接入層統(tǒng)一處理避免開發(fā)圖表時每個模塊各自寫一套“在線”判斷。3.2 實時計算鏈路選型Kafka 流處理 Redis 時間序列庫畫大屏的數(shù)據(jù)鏈路我最推薦的是下面這條組合拳Agent 通過 MQTT/HTTP 把狀態(tài)上報到 Harness 網(wǎng)關(guān)網(wǎng)關(guān)校驗后寫入 Kafka。使用 Kafka Streams 或者輕量的消費者程序?qū)ο⒆銮逑?、聚合計?1 分鐘粒度的心跳成功率、任務(wù)成功率、平均耗時。聚合結(jié)果寫入 Redis用于大屏實時顯示當(dāng)前值和時序數(shù)據(jù)庫用于趨勢圖和歷史回放。大屏服務(wù)端通過 WebSocket 訂閱 Redis 的變更事件推送數(shù)據(jù)到前端。你可能想問為什么不能直接讓大屏查 DataFrame 或者查 MySQL原因很簡單大屏的加載頻率特別高如果每次整屏刷新都打到業(yè)務(wù)庫會給正常業(yè)務(wù)帶來無謂的壓力。Harness 層的數(shù)據(jù)庫必須保證核心寫入性能不能承擔(dān)頻繁聚合查詢的負(fù)擔(dān)。時序庫我們用的是 VictoriaMetrics選它不選別的主要是上線成本極低單機模式就能扛住每秒幾十萬的指標(biāo)寫入而且兼容 PromQL查詢語法生態(tài)齊全。當(dāng)時也糾結(jié)過要不要直接上 ClickHouse后來想通了我們大屏核心是在線數(shù)和成功率這種流式聚合不是海量明細(xì)的隨意切片分析VictoriaMetrics 的定位更貼合需求。3.3 為什么最終沒有用統(tǒng)一網(wǎng)關(guān)存所有日志第一版架構(gòu)里我心血來潮想把 Agent 執(zhí)行產(chǎn)生的所有日志也走 Kafka 存下來用于“大屏上看日志預(yù)覽”。后來發(fā)現(xiàn)代價很高很容易把大屏這個“狀態(tài)可視化系統(tǒng)”做成一個“日志搜索系統(tǒng)”預(yù)算和精力分配都崩了。想清楚后我們做了個取舍大屏只接收結(jié)構(gòu)化的指標(biāo)和輕量事件比如狀態(tài)變更、任務(wù)開始結(jié)束、異常碼而完整執(zhí)行日志仍走獨立的文件或日志平臺。監(jiān)控大屏的核心能力是在一堆狀態(tài)里快速發(fā)現(xiàn)異常而不是提供逐行日志閱讀的沉浸體驗。如果想看某異常 Agent 的細(xì)節(jié)在大屏上點擊一個節(jié)點跳轉(zhuǎn)到日志平臺帶參查詢即可沒必要把兩個系統(tǒng)硬揉在一起。4. 大屏前端實現(xiàn)可視化框架選擇與顯示細(xì)節(jié)4.1 可視化圖表庫選型ECharts 為主體Canvas 為輔助到了前端部分這才是很多人印象里的“可視化大屏”工作。我們選型時對比了一陣。主框架用的是 Vue 3這一層因團隊熟悉度不同沒有絕對標(biāo)準(zhǔn)。重點是圖表庫我們選擇了 Apache ECharts。理由有三點內(nèi)置地圖和雷達圖等圖表類型多官方文檔全社區(qū)踩坑案例多在大數(shù)據(jù)量下支持 Canvas 渲染而不是 SVG節(jié)點幾千個時依然流暢。偶爾需要極高性能的節(jié)點拓?fù)鋾r再用 Canvas 手寫繪制比如“全網(wǎng) Agent 連接拓?fù)洹辈⒉皇浅i_而是作為輔助 tab 存在。如果你還在猶豫選 ECharts 還是 AntV我的建議是先看團隊更熟悉哪個。它們能力都很強。但如果你可能用到自定義大屏背景和復(fù)雜的飛線效果ECharts 能省不少事如果有比較強烈的統(tǒng)計分析需求AntV 的統(tǒng)計圖表會更順手。4.2 大屏頁面結(jié)構(gòu)設(shè)計狀態(tài)總覽、趨勢、節(jié)點拓?fù)浔O(jiān)控大屏不是一屏展示越多越好。我們做了三塊區(qū)域中央主視圖顯示 Harness 層管理下的 Agent 集群實時在線率配一張按區(qū)域分布的縮略地圖用色階從綠到紅展示健康度。左側(cè)趨勢區(qū)當(dāng)前時刻往前推 24 小時的任務(wù)成功率、心跳延遲變化方便觀察長期趨勢。右側(cè)異常列表區(qū)實時滾動顯示離線 Agent 和高延遲 Agent。為何這樣布局觀察順序是先看整體健康狀態(tài)再橫向?qū)Ρ葧r段趨勢最后下鉆到具體異常實體。我們在實際試運行中收到不少好評因為操作人員不用來回切換 Tab 就能完成“感知異?!_認(rèn)范圍—點擊進入詳情”三步。4.3 接口推送方案用 WebSocket 代替輪詢在數(shù)據(jù)刷新上高實時大屏最主要的一個經(jīng)驗是不要用 setInterval 每 5 秒拉一次全量接口。否則當(dāng)頁面放大到大屏 4K 分辨率時瀏覽器幀率會明顯掉下來。我們的做法是頁面初載時調(diào)用一次 HTTP 接口拿全量基礎(chǔ)數(shù)據(jù)之后只通過 WebSocket 接收增量推送。每個推送消息帶有自增時間戳前端去重后每 2 秒合并進圖表的數(shù)據(jù)集。這樣既減輕后端壓力也讓幀率保持穩(wěn)定。同時WebSocket 自動斷線重連邏輯必須做而且要處理“重連后立即拉取一次全量同步”避免斷線期間圖表數(shù)據(jù)產(chǎn)生空洞。4.4 視覺呈現(xiàn)的細(xì)節(jié)不是越炫越好很多網(wǎng)上的“可視化大屏背景”預(yù)設(shè)第一眼看著很酷但放到業(yè)務(wù)狀態(tài)監(jiān)控上未必合適。大量的漸變、粒子動畫雖然適合展廳大屏卻對日常盯守是一種干擾。我們的取舍原則是只有狀態(tài)異常時使用醒目的紅色或閃爍提醒正常狀態(tài)盡量用偏冷淡的藍綠色。圖表邊框盡量細(xì)背景使用深色但不必有好幾層光暈。這樣做的目的是讓值班人員掃一眼就能判斷“這個系統(tǒng)是否正?!倍皇敲看味家屑?xì)辨析顏色深淺。5. 實操中避不開的坑狀態(tài)漂移、數(shù)據(jù)不一致與告警疲勞5.1 狀態(tài)漂移顯示的在線和實際不一致在這類監(jiān)控項目中最常見的坑就是“狀態(tài)漂移”。比如大屏顯示 Agent 在線但實際 Agent 已經(jīng)假死不再執(zhí)行任務(wù)。造成這種問題的原因通常是心跳機制不夠嚴(yán)格。心跳和真實能力無關(guān)一個阻塞在 IO 上的 Agent 依然能發(fā)送心跳。我們在心跳之外增加了“任務(wù)探活”Harness 每 30 秒隨機選擇少量 Agent 發(fā)送一個輕量級的 ping 指令并要求收到 pong 響應(yīng)。只有心跳成功且最近 ping 響應(yīng)正常的 Agent 才被標(biāo)記為“健康”。大屏上展示的在線率改成健康率比單純在線率更有操作指導(dǎo)意義。5.2 大屏數(shù)據(jù)對不上明細(xì)系統(tǒng)數(shù)據(jù)不一致問題在很多可視化項目里都存在。我們已經(jīng)要求統(tǒng)一指標(biāo)口徑但還有另一個常見來源時間窗口和時區(qū)。比如任務(wù)成功率如果按開始時間聚合那跨天任務(wù)會算到前一天還是后一天不同報表之間會有差異。大屏數(shù)據(jù)與 Excel 報表不一致的問題常有人理解成“大屏顯示錯了”實則不是錯而是聚合維度不同。這次我們專門統(tǒng)一了所有數(shù)據(jù)產(chǎn)品的默認(rèn)口徑窗口按 Agent 任務(wù)結(jié)束時間歸入當(dāng)天統(tǒng)計。這一點建議越早定越好最好在項目的指標(biāo)字典里直接寫明。5.3 監(jiān)控大屏沒人看、報警風(fēng)暴的連鎖反應(yīng)一個獨立監(jiān)控大屏最容易產(chǎn)后失去價值不是說不再顯示而是大家都習(xí)以為常。上線第一周新鮮感還在到了第四周基本沒人主動看。啟動原因往往是所有該暴露的問題都被告警轟炸過已經(jīng)麻木。我們的應(yīng)對措施是給大屏加了一個“溫和升級”機制對于離線 Agent按照兩個等級展示一個是瞬時斷連、一個是持續(xù)離線超過 10 分鐘。只有持續(xù)離線才會觸發(fā)嚴(yán)重告警。同時在頁面頂部留出一行“最近 1 小時恢復(fù)”的指標(biāo)讓團隊看到我調(diào)整配置后發(fā)生的問題確實在減少形成正向反饋。坦白說這部分已經(jīng)超出了“做圖表”的范疇但正是這種產(chǎn)品化思維讓大屏最終真正成為大家每天開會都會掃一眼的地方。6. 上線后的最佳實踐與遷移擴展建議任何平臺都不可能一成不變。Harness 層監(jiān)控大屏跑了一段時間后會有幾個重要的擴展方向。其一是做 Agent“狀態(tài)預(yù)測”。我們通過時序庫中保存的歷史數(shù)據(jù)對 Agent 離線趨勢做了簡單回歸預(yù)測比如未來半小時內(nèi)某區(qū)域的 Agent 離線率可能超過閾值系統(tǒng)提前給出預(yù)警。實現(xiàn)思路不復(fù)雜但收益明顯優(yōu)于事后告警。需要注意的是預(yù)測僅適合作為參考不要直接驅(qū)動自動運維動作避免誤操作影響業(yè)務(wù)。其二是把可視化能力開放給業(yè)務(wù)方。我們提供了類似 SQL 查詢的 API讓各業(yè)務(wù)線可以自行拉取他們關(guān)心的 Agent 專屬指標(biāo)而不必每個需求都改動大屏。大屏本身只維護一套統(tǒng)一基線視圖細(xì)節(jié)交給自助分析。第三個和前面說到的實時鏈路相關(guān)如果在當(dāng)前架構(gòu)下 Kafka 消費能力成為瓶頸優(yōu)先檢查和調(diào)整分區(qū)數(shù)而不是盲目抬高消費線程。出現(xiàn)積壓時在大屏數(shù)據(jù)流上有滯后感卻不能丟數(shù)據(jù)這是我們實際的經(jīng)驗具體分區(qū)策略要按上報量峰值來判斷沒有統(tǒng)一最好的配置只有最匹配當(dāng)下來流量模型的配置。最后提醒一句這種 Harness 層監(jiān)控可視化項目最怕一步到位。第一版可以做概要視圖把在線率、成功率、離線數(shù)這幾個核心指標(biāo)跑通第二版再考慮節(jié)點拓?fù)湎裸@和異常歸類。先把鏈路打通確定數(shù)據(jù)可靠的根后面視覺層的東西都是錦上添花。