:自研輕量資源監(jiān)控工具rea的完整實踐)
很多朋友看到rea這個標(biāo)題時大概率會以為打錯了字或者覺得這是某個庫的縮寫。我要先坦白一件事——它最初真沒有什么標(biāo)準(zhǔn)全稱只是某天我在終端里隨手敲的三個字母用來命名一個空目錄。后來這個目錄慢慢長成了一個完整的資源效率分析工具Resource Efficiency Analyzer內(nèi)部代號縮寫就是rea專門負(fù)責(zé)采集服務(wù)器的CPU、內(nèi)存、磁盤與網(wǎng)絡(luò)指標(biāo)再把這些數(shù)據(jù)整理成實時看板幫我從被動救火式運維變成主動觀察式管理。這篇文章就把一個模糊標(biāo)題如何變成一個可運行系統(tǒng)的完整過程寫出來適合手里有個想法、但還沒想清楚架構(gòu)的開發(fā)者參考也適合那些想自建一套輕量監(jiān)控體系、又不想直接套用重型全家桶的朋友。1. 先給 rea 一個定義從模糊代號到明確需求1.1 代號背后的真實需求別再讓服務(wù)器走在下線邊緣見過凌晨兩點的告警郵件嗎說的不是那種CPU 忽高忽低再觀察一下的假警報而是磁盤使用率沖到 98%數(shù)據(jù)庫進(jìn)程直接崩掉然后你在睡夢中被電話叫起來瞇著眼睛查哪張表把空間吃光了。我經(jīng)歷過幾次這種場景之后決定不能再靠感覺運維了。我需要一個工具能持續(xù)地告訴我每一臺機器的資源消耗長什么樣不是事后翻日志而是事前能看到趨勢。rea 的第一個需求就這么定下來了采集多臺服務(wù)器的系統(tǒng)資源指標(biāo)存入數(shù)據(jù)庫用圖表展示歷史趨勢。聽起來很簡單但里面藏了幾個硬約束。一是采集不能太影響業(yè)務(wù)agent 本身要輕二是數(shù)據(jù)量會持續(xù)增長存儲和查詢得接得住三是展示要讓人能快速定位問題不能打開看板還要等十幾秒。給項目起代號的時候我壓根沒花心思。rea 就是 resource efficiency analyzer 的縮寫順手打的也沒打算對外發(fā)布。但正式動手前我給自己寫了一段項目說明用最低的運維成本記錄基礎(chǔ)設(shè)施的資源水位讓趨勢可見、異??刹椤_@段話后來幫我擋掉了不少需求膨脹的沖動誰再說順便加個 XX 功能我就把這段話翻出來給他看。1.2 誰是它的目標(biāo)用戶我為什么不做成通用監(jiān)控平臺市面上的監(jiān)控平臺很多從老牌開源方案到商業(yè)全家桶隨便挑一個都能用。但我做 rea目標(biāo)用戶從一開始就只有兩類一個是我自己另一個是和我類似的小團(tuán)隊——機器數(shù)量在 5 到 30 臺之間沒有專職運維預(yù)算有限又不想為了看幾個指標(biāo)把整套重型框架搬回家。自研的邊界一定要劃清楚。我不追求覆蓋所有監(jiān)控場景也不打算做高可用集群。rea 要解決的是 80% 的常見問題機器負(fù)載有沒有異常、內(nèi)存是不是長期吃緊、磁盤大概還有多少天會被寫滿、網(wǎng)絡(luò)流量是不是有突發(fā)。至于分布式鏈路追蹤、日志檢索、APM 這類能力那是另外的戰(zhàn)場硬塞進(jìn)來只會讓項目失焦。而且自建這條路有個隱形好處整個系統(tǒng)從采集到展示都是自己寫的每個環(huán)節(jié)都清楚出了問題不會像黑盒一樣無從下手。公司里如果買了商業(yè)產(chǎn)品排障時只能提工單用開源方案遇到不滿足的場景得讀源碼改插件。而 rea 是我自己的我想讓它支持什么業(yè)務(wù)指標(biāo)直接加一個字段就行這種掌控感用錢買不到。2. 技術(shù)方案怎么定三層結(jié)構(gòu)是小項目的保命符2.1 為什么第一反應(yīng)不是全家桶監(jiān)控系統(tǒng)有現(xiàn)成的開源監(jiān)控組合可用為什么要自己寫這個問題我在動手前認(rèn)真回答過自己。最直接的原因是學(xué)習(xí)成本。全家桶方案確實強大但它的學(xué)習(xí)曲線很陡配置項非常多默認(rèn)參數(shù)不一定適合你的場景踩坑時要在告警規(guī)則、服務(wù)發(fā)現(xiàn)、模板變量之間來回排查。我見過不少團(tuán)隊把監(jiān)控系統(tǒng)裝起來了結(jié)果沒人會配告警閾值最后變成一個昂貴的圖表庫。另一個原因是業(yè)務(wù)指標(biāo)接入的靈活性。系統(tǒng)監(jiān)控指標(biāo)可以用現(xiàn)成方案采集但業(yè)務(wù)指標(biāo)比如某個核心接口的響應(yīng)時間、某條消息隊列的積壓數(shù)量、今天新增的訂單量這些需要業(yè)務(wù)代碼主動上報。與其在自研系統(tǒng)之外再接一套上報通道不如把 rea 做成一個通用的指標(biāo)接收器無論是系統(tǒng)數(shù)據(jù)還是業(yè)務(wù)數(shù)據(jù)只要按約定格式推過來就能落庫、查詢、展示。當(dāng)然現(xiàn)成方案也有它的價值。我并沒有完全否定它只是在 rea 這個特定項目里我希望它足夠輕、足夠可控。如果哪天機器規(guī)模漲到上百臺需要服務(wù)發(fā)現(xiàn)、自動告警、多租戶隔離這些能力到時候再評估遷移也不遲。先解決眼前的問題不為了未來可能的規(guī)模提前背上復(fù)雜度的包袱。2.2 前后端與存儲選型的一個參考組合rea 的技術(shù)棧沒有用花哨的新框架全是經(jīng)得起時間考驗的組合。前端選了 Vue3 加 TypeScript用 Vite 做構(gòu)建工具圖表庫用 ECharts。后端用 Python 的 FastAPI接口寫起來快性能也夠用。存儲這塊是重頭戲選的是 TimescaleDB跑在 PostgreSQL 之上既保留關(guān)系數(shù)據(jù)庫的熟悉感又針對時序數(shù)據(jù)做了專門優(yōu)化。選擇依據(jù)其實很務(wù)實環(huán)節(jié)選型核心理由前端框架Vue3 TypeScript Vite組件化清晰類型安全開發(fā)效率高圖表庫ECharts折線圖、面積圖開箱即用大數(shù)據(jù)量渲染有內(nèi)置優(yōu)化后端框架Python FastAPI異步支持好自動生成接口文檔開發(fā)速度快數(shù)據(jù)存儲TimescaleDB原生支持時序表分區(qū)壓縮率高SQL 查詢降低成本部署方式Docker Compose Nginx一套命令拉起全部依賴適合小規(guī)模場景為什么不用 MySQL 或者 MongoDBMySQL 存時序數(shù)據(jù)不是不行但數(shù)據(jù)量上來后按時間范圍刪除舊數(shù)據(jù)、按時間窗口聚合這些操作都會變得別扭。MongoDB 文檔模型靈活但聚合查詢寫起來不如 SQL 直觀而且對時間序列的壓縮能力幾乎沒有。TimescaleDB 本質(zhì)上還是 SQL我可以用熟悉的 JOIN 和 GROUP BY同時獲得自動分區(qū)和壓縮帶來的性能紅利這是它最打動我的地方。2.3 一次架構(gòu)的簡化-膨脹-再簡化很多個人項目死在想得太多上rea 也不例外。最初畫架構(gòu)圖的時候我列了一堆組件消息隊列緩沖采集流量流處理引擎做實時聚合NoSQL 存原始數(shù)據(jù)寬表存聚合數(shù)據(jù)再配一套 Redis 做緩存前端還要考慮 WebSocket 推送。畫完之后自己看著都害怕這哪是個人工具這是照著大型互聯(lián)網(wǎng)公司的基礎(chǔ)設(shè)施在搭。后來我做了個減法把架構(gòu)壓縮成三條鏈路采集器定時把指標(biāo) POST 到后端接口后端寫入數(shù)據(jù)庫前端通過查詢接口取數(shù)繪圖。中間的消息隊列和流處理全部去掉理由是數(shù)據(jù)量沒有大到需要異步削峰的程度一臺采集器 10 秒上報一次20 臺機器也就每秒兩條請求FastAPI 處理這點請求綽綽有余。這個砍需求的過程讓我學(xué)到一點小項目最值錢的優(yōu)勢就是簡單任何你覺得以后可能用得上的組件都先記在文檔里而不是裝進(jìn)代碼里。真到了需要消息隊列的那天再把它加進(jìn)來而不是一開始就為想象中的人流量修一條十車道的高速公路。3. 核心鏈路落地采集、寫入、查詢、展示一個都不能少3.1 數(shù)據(jù)表設(shè)計時序數(shù)據(jù)的第一課rea 落地的第一個關(guān)鍵環(huán)節(jié)是數(shù)據(jù)庫表結(jié)構(gòu)。時序數(shù)據(jù)的特點是寫多讀少、數(shù)據(jù)只追加、舊數(shù)據(jù)需要定期清理所以表結(jié)構(gòu)不能照搬普通業(yè)務(wù)表。我建的第一張表是主機資源指標(biāo)表核心字段包括采集時間、主機名、CPU 使用率、內(nèi)存使用率、磁盤使用率、網(wǎng)絡(luò)流入量、網(wǎng)絡(luò)流出量以及一個 JSONB 類型的擴展字段。建表語句如下CREATE TABLE host_metrics ( time TIMESTAMPTZ NOT NULL, host TEXT NOT NULL, cpu_usage DOUBLE PRECISION, mem_usage DOUBLE PRECISION, disk_usage DOUBLE PRECISION, net_in BIGINT, net_out BIGINT, tags JSONB DEFAULT {} ); SELECT create_hypertable(host_metrics, by_range, time);這里有幾個設(shè)計細(xì)節(jié)值得展開說一下。第一個是為什么用TIMESTAMPTZ而不是TIMESTAMP。時序數(shù)據(jù)最怕時區(qū)混亂如果用不帶時區(qū)的TIMESTAMP采集器從不同時區(qū)的機器上報數(shù)據(jù)時時間軸會錯位。統(tǒng)一用帶時區(qū)的類型所有時間都按 UTC 存儲展示層再按用戶時區(qū)轉(zhuǎn)換這是最不容易出錯的方案。第二個是為什么保留一個tags字段。單臺機器的指標(biāo)字段是固定的但業(yè)務(wù)上可能想給不同機器打標(biāo)簽比如區(qū)分線上環(huán)境、測試環(huán)境或者標(biāo)注機器所屬的可用區(qū)。把這些維度塞進(jìn)單獨的列會很死板放在 JSONB 里就靈活多了查詢時用tags-env就能做過濾。第三個是為什么time和host不加聯(lián)合主鍵。剛開始我也習(xí)慣性地想加后來實測發(fā)現(xiàn)唯一約束會嚴(yán)重拖慢寫入速度時序數(shù)據(jù)本身就帶有時間戳這個天然標(biāo)識重復(fù)數(shù)據(jù)靠應(yīng)用層去重就夠了數(shù)據(jù)庫層的唯一性約束在這里性價比很低。3.2 寫一個不添亂的采集器采集器是 rea 的神經(jīng)末梢它要足夠輕不能給被監(jiān)控的機器添亂。我用 Python 的 psutil 庫實現(xiàn)資源采集這個庫的優(yōu)勢是跨平臺、接口穩(wěn)定、文檔全Linux 和 Windows 都能跑對個人項目來說覆蓋面足夠了。核心采集邏輯比較直接import socket import time import requests import psutil INTERVAL 10 ENDPOINT http://rea-server:8080/api/metrics def collect_once(): return { host: socket.gethostname(), cpu_usage: psutil.cpu_percent(interval1), mem_usage: psutil.virtual_memory().percent, disk_usage: psutil.disk_usage(/).percent, net_in: psutil.net_io_counters().bytes_recv, net_out: psutil.net_io_counters().bytes_sent, ts: int(time.time()) } while True: try: data collect_once() requests.post(ENDPOINT, jsondata, timeout3) except Exception as exc: log_to_file(freport failed: {exc}) time.sleep(INTERVAL)代碼看著簡單但有幾個細(xì)節(jié)如果處理不好后續(xù)會相當(dāng)難受。第一個是cpu_percent的interval參數(shù)。psutil.cpu_percent(interval0)是絕大多數(shù)初學(xué)者的寫法結(jié)果往往返回 0因為第一次調(diào)用沒有歷史采樣數(shù)據(jù)。代碼里傳interval1含義是阻塞 1 秒、計算這 1 秒內(nèi)的平均使用率這樣第一次拿到的值就是可信的。當(dāng)然這 1 秒阻塞是可以接受的畢竟采集頻率本來就不高。第二個是網(wǎng)絡(luò)流量讀的是累積值而不是速率。bytes_recv和bytes_sent是從開機以來的累計字節(jié)數(shù)存到數(shù)據(jù)庫里之后繪圖時要用當(dāng)前值減去上一時刻值再除以時間間隔才能得到平均速率。我可以選擇在采集器里先把速率算好也可以把累積值存下來交給查詢端計算。我選了后者理由是想保留最原始的計數(shù)這樣即使后來想調(diào)整時間窗口也能靈活重算。第三個是采集器不需要花哨的并發(fā)能力單線程循環(huán)加異常隔離就足夠了。上傳失敗不能影響采集日志要寫到文件而不是控制臺不然服務(wù)跑起來之后根本看不到報錯。啟動之后先用一次cpu_percent(None)做預(yù)熱避免第一次上報的數(shù)據(jù)點失真這也是容易忽略的小坑。3.3 服務(wù)端接口別讓單條寫入拖垮寫入性能后端接口是整個鏈路的中轉(zhuǎn)站它要同時面對兩個問題來自多臺采集器的持續(xù)寫入請求以及來自前端的時間范圍查詢請求。寫入接口的寫法一定要考慮批量處理。最直觀的做法是每收到一條數(shù)據(jù)就 INSERT 一條但這樣做數(shù)據(jù)庫壓力會大連接頻繁開關(guān)TPS 一口就被壓死了。我采用的方案是內(nèi)存隊列加定時 flush。接口收到指標(biāo)后先把數(shù)據(jù)放進(jìn)一個線程安全的隊列后臺任務(wù)每隔 5 秒或者隊列累積到 500 條時統(tǒng)一執(zhí)行批量插入。這樣數(shù)據(jù)庫每次操作面對的是一批數(shù)據(jù)寫入吞吐量能差出一個數(shù)量級。下面是簡化后的核心結(jié)構(gòu)import asyncio import asyncpg from fastapi import FastAPI app FastAPI() _batch [] async def flush_batch(): if not _batch: return records _batch[:] _batch.clear() async with pool.acquire() as conn: await conn.executemany( INSERT INTO host_metrics (time, host, cpu_usage, mem_usage, disk_usage, net_in, net_out, tags) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) , records ) app.post(/api/metrics) async def receive_metrics(item: MetricItem): _batch.append(( datetime.fromtimestamp(item.ts, tztimezone.utc), item.host, item.cpu_usage, item.mem_usage, item.disk_usage, item.net_in, item.net_out, json.dumps(item.tags) )) if len(_batch) 500: await flush_batch() return {status: ok}這個設(shè)計的關(guān)鍵不只是批量還包括失敗重試和容量控制。如果后臺 flush 任務(wù)拋異常不能把隊列里已有的數(shù)據(jù)丟掉要記錄日志并保留備份否則會出現(xiàn)看板缺數(shù)據(jù)的詭異現(xiàn)象。隊列本身也需要一個上限比如最大 5000 條超過上限的請求先返回錯誤而不是無限堆積內(nèi)存否則采集器一旦異常大量上報后端的進(jìn)程內(nèi)存會被撐爆這時候反而需要采集端主動降頻。3.4 查詢與前端看板如何讓頁面不卡數(shù)據(jù)寫進(jìn)去之后查詢接口要能支持時間范圍、主機過濾、指標(biāo)選擇這些常見條件。最關(guān)鍵的一個優(yōu)化是降采樣。一張時序表里如果存了數(shù)十萬條數(shù)據(jù)前端小屏幕根本畫不下強行渲染只會讓頁面卡死。SQL 層用time_bucket函數(shù)把秒級數(shù)據(jù)聚合成分鐘級或小時級數(shù)據(jù)曲線既平滑又輕量這才是正確姿勢。一個典型的趨勢查詢是這樣的SELECT time_bucket(1 minute, time) AS bucket, host, avg(cpu_usage) AS cpu_avg, max(cpu_usage) AS cpu_max FROM host_metrics WHERE host $1 AND time $2 AND time $3 GROUP BY bucket, host ORDER BY bucket;前端看圖只關(guān)心大體趨勢分鐘級均值足夠用了。如果用戶想看某個瞬間的精確值再加一個下鉆接口返回原始明細(xì)數(shù)據(jù)這樣的兩級策略兼顧體驗和性能。前端看板用的是 Vue3 加 ECharts。整體布局分三塊頂部是時間范圍選擇器左側(cè)是主機列表中間是多個指標(biāo)折線圖。主機列表支持多選選中的每臺機器用不同顏色區(qū)分時間范圍改變后所有圖表聯(lián)動刷新。實現(xiàn)聯(lián)動時有一個并發(fā)問題要注意多個請求同時發(fā)出返回順序可能不一致后返回的舊數(shù)據(jù)不能覆蓋新數(shù)據(jù)。我用請求序號做了一層校驗只渲染最后一次發(fā)起的請求結(jié)果這個細(xì)節(jié)花了我一晚上才定位到。4. 部署細(xì)節(jié)與踩坑實錄rea 從本機跑到服務(wù)器的過程4.1 Docker Compose 一鍵拉起整套環(huán)境rea 的部署目標(biāo)是一臺 2C4G 的云服務(wù)器所有組件用 Docker Compose 管理。這個選擇意味著環(huán)境依賴被全部封進(jìn)容器換機器、重新部署都很從容不用在一臺新服務(wù)器上手動裝 Python、Node、PostgreSQL也避免版本不一致的問題。docker-compose.yml 的骨架如下version: 3.8 services: timescaledb: image: timescale/timescaledb:latest-pg16 environment: POSTGRES_PASSWORD: rea_db_pass POSTGRES_DB: rea volumes: - rea_db_data:/var/lib/postgresql/data ports: - 5432:5432 rea-server: build: ./server environment: DATABASE_URL: postgresql://postgres:rea_db_passtimescaledb:5432/rea depends_on: - timescaledb ports: - 8080:8080 rea-web: build: ./web ports: - 80:80 depends_on: - rea-server volumes: rea_db_data:容器化部署里有幾個容易踩的點。第一個是數(shù)據(jù)庫數(shù)據(jù)卷必須單獨掛載否則容器一刪數(shù)據(jù)全沒。第二個是容器之間通信用服務(wù)名而不是 IP因為每次重建容器 IP 都可能變而timescaledb這個服務(wù)名在 Compose 網(wǎng)絡(luò)內(nèi)是穩(wěn)定的。第三個是整個鏈路的前端與后端分離部署前端服務(wù)不僅負(fù)責(zé)提供靜態(tài)頁面還要用 Nginx 反向代理后端接口這樣頁面里的請求地址可以統(tǒng)一寫相對路徑避免瀏覽器跨域問題。4.2 我踩過的四個坑每一個都是性能殺手rea 從能跑變成好跑的過程中我踩了不少坑撿四個印象最深的分享出來。第一個是唯一約束拖垮寫入性能。開始建表時我習(xí)慣性地加了PRIMARY KEY (host, time)想著防止重復(fù)數(shù)據(jù)結(jié)果寫入一壓測TPS 只有幾百完全不是 TimescaleDB 該有的水平。去掉唯一約束之后寫入吞吐直接翻了幾倍。時序場景下重復(fù)數(shù)據(jù)很少偶爾重復(fù)也可以容忍數(shù)據(jù)庫不應(yīng)為不可能發(fā)生的情況買單。第二個是時區(qū)混亂導(dǎo)致曲線偏移八小時。采集器上報的是 UTC 時間前端 ECharts 默認(rèn)按瀏覽器本地時間格式化看起來所有曲線都平移了一段。折騰了半天才發(fā)現(xiàn)是時區(qū)問題?,F(xiàn)在我的原則是通信全程用時間戳展示層轉(zhuǎn)成用戶本地時間數(shù)據(jù)庫里統(tǒng)一存 UTC三層各管一段絕不混用。第三個是cpu_percent首次調(diào)用返回 0。這個問題說起來有點可笑但新手真的會碰到。psutil 的 CPU 使用率計算依賴前后兩次調(diào)用之間的差值第一次調(diào)用沒有基準(zhǔn)直接返回 0。在采集器啟動后先做一次預(yù)熱調(diào)用問題就消失了。第四個是前端圖表一次性拉全量數(shù)據(jù)導(dǎo)致瀏覽器崩潰。最初我沒做降采樣一次查 7 天秒級數(shù)據(jù)幾萬甚至十幾萬個點ECharts 直接卡成幻燈片。后來改成time_bucket降采樣加 ECharts 自帶的sampling: lttb圖表不卡了加載速度也快了。在數(shù)據(jù)可視化里聰明地丟棄細(xì)節(jié)比死磕完整性重要得多。4.3 常見問題速查表把日常運行中出現(xiàn)過的問題整理成一張速查表方便自己排查也方便后來者現(xiàn)象可能原因處理方式看板長時間沒有新數(shù)據(jù)采集器進(jìn)程掛了或網(wǎng)絡(luò)不通檢查采集器日志telnet 測試接口連通性數(shù)據(jù)庫磁盤快速增長保留策略未配置舊數(shù)據(jù)無限堆積添加定時任務(wù)刪除超期數(shù)據(jù)圖表曲線出現(xiàn)缺口批量寫入失敗且無重試檢查后端日志確認(rèn) flush 隊列是否丟失數(shù)據(jù)跨天數(shù)據(jù)時間軸錯亂采集端時區(qū)與數(shù)據(jù)庫不一致統(tǒng)一用 UTC 時間戳展示層再做時區(qū)轉(zhuǎn)換多臺機器曲線顏色重復(fù)前端只按主機名取色主機名過短改用主機列表的索引作為顏色區(qū)分依據(jù)查詢接口響應(yīng)越來越慢沒有按時間范圍建立索引確保time列有索引查詢盡量帶時間下推條件5. 給 rea 留出的后路從監(jiān)控工具變成分析平臺5.1 告警、預(yù)測、權(quán)限優(yōu)先級怎么排rea 目前已經(jīng)能穩(wěn)定采集和展示了接下來要擴展的方向按優(yōu)先級排告警第一預(yù)測第二權(quán)限第三。告警最好做因為數(shù)據(jù)已經(jīng)有了只需要在后端加一個定時檢查任務(wù)對最近一分鐘的指標(biāo)做閾值判斷觸發(fā)條件時把消息推到通知渠道。這個功能能極大降低人肉盯看板的頻率算是對自由時間的解放。預(yù)測功能更有意思也更能體現(xiàn)數(shù)據(jù)分析的價值。比如磁盤使用率可以根據(jù)過去三十天的增長趨勢做線性擬合估算出按當(dāng)前速度還能用幾天。這種預(yù)測不需要復(fù)雜的機器學(xué)習(xí)模型最小二乘法就夠了但它的提醒效果比生硬的閾值告警好得多讓人有充分的緩沖時間去清理或擴容。權(quán)限這塊暫時不急因為目前只有我自己在看。但如果未來某個團(tuán)隊要用多用戶體系就必須考慮了。我的思路是在 API 層面加一層 Token 鑒權(quán)前端每個請求帶上身份標(biāo)識后端按用戶維度限制可見的主機范圍。暫時不需要引入完整的關(guān)系權(quán)限模型保持簡單等需求真的來了再細(xì)化。5.2 業(yè)務(wù)指標(biāo)接入后看板才真正有生命力系統(tǒng)資源指標(biāo)只能告訴你基礎(chǔ)設(shè)施健不健康但業(yè)務(wù)指標(biāo)才是決定要不要立刻起床的關(guān)鍵。rea 的上報接口是通用的這意味著業(yè)務(wù)代碼可以把關(guān)鍵指標(biāo)直接 POST 進(jìn)來和系統(tǒng)指標(biāo)存在同一張鏈路里看板就能把業(yè)務(wù)異常和資源異常對照著看。比如某個核心服務(wù)響應(yīng)時間突然上漲很可能是部署機器 CPU 被打滿導(dǎo)致的。只看業(yè)務(wù)指標(biāo)你只知道慢了只看 CPU 指標(biāo)你不知道它影響到什么。兩個維度疊加在一個時間軸上看因果關(guān)系就清晰多了。我的做法是給業(yè)務(wù)指標(biāo)加一個metric_type標(biāo)識字段系統(tǒng)指標(biāo)使用system業(yè)務(wù)指標(biāo)使用business查詢時既可以在同一張圖上疊加展示也可以按類型分開過濾。我在實際使用中還有一個體會是自研監(jiān)控最有價值的點不是省掉了采購成本而是在這個過程中建立的數(shù)據(jù)第一的觀念。當(dāng)你連續(xù)觀察了一段時間的曲線之后你會開始相信數(shù)據(jù)而不是直覺。以前我總覺得機器快不行了打開看板一看流量平穩(wěn)心里就踏實了有時候我感覺一切正常但曲線顯示內(nèi)存緩緩爬升反而能提前發(fā)現(xiàn)隱患。這種感覺用任何人都給你裝不上的監(jiān)控配方也換不來。最后再分享一個小技巧如果你也想做類似的項目名字叫什么并不重要哪怕像我一樣隨手敲三個字母也行。重要的是從第一天開始就把數(shù)據(jù)模型當(dāng)成地基來打采集頻率、存儲格式、時間精度這些基礎(chǔ)決策一旦定了后面很難改改一次就牽一發(fā)動全身。先把地基打穩(wěn)再慢慢加樓層。