
微服務日常巡檢的檢查順序微服務巡檢不是每天把所有指標看一遍。更有效的做法是先確認用戶路徑是否異常再沿入口、依賴、線程與連接池、JVM 和基礎設施逐層縮小范圍。順序清楚值班人員才能知道下一步該看什么也能避免一看到 CPU 抖動就重啟服務。巡檢項要跟隨系統風險和依賴變化維護。新接入消息隊列、修改線程池、升級 JDK 或調整注冊中心后對應檢查也要更新一份多年不變的靜態清單很快會與真實架構脫節。第一層先看用戶請求和近期變更從關鍵入口的成功率、目標延遲和任務完成情況開始并按路由或業務類型分組。整體平均值正常可能仍有一個高價值接口持續失敗。流量接近零時成功率也可能失真應同時看請求量和絕對錯誤數。把當前異常與最近發布、配置變更、依賴升級和流量變化放在同一時間軸。時間接近不等于根因已經確認但它能幫助確定優先排查范圍。沒有異常時日常報告也應標明當前版本和上次變更方便后來對比。健康檢查只是一條信號。Liveness 回答進程是否需要重啟Readiness 決定實例能否接流業務路徑則驗證關鍵功能。端口可訪問不能證明線程池、數據庫和注冊狀態正常反過來下游短時波動也不應觸發所有實例的 Liveness 失敗并反復重啟。第二層檢查依賴和流量放大查看上游到本服務、再到數據庫、緩存、消息隊列和其他 RPC 的調用關系。重點是超時、重試、連接等待和拒絕。入口流量沒有變化、內部調用卻明顯增加可能出現重試放大或重復消費。依賴異常時先確認是所有實例都失敗還是某個可用區、連接池或目標版本集中出錯。DNS、證書和權限錯誤通常不會通過原樣重試恢復連接中斷或明確的臨時錯誤才可能在預算內有限重試。巡檢報告需要保留錯誤分類而不是統一寫成“下游不穩定”。服務發現要同時看控制面與調用端實際視圖。注冊中心有實例不代表客戶端緩存已經更新實例心跳正常也不代表業務處理能力正常。可以抽查注冊版本、實例狀態和一次真實路由結果但不要讓巡檢繞過正常負載均衡直接修改注冊信息。第三層看線程池、連接池和隊列Java 服務常見的“CPU 不高卻很慢”往往與等待有關。檢查業務線程池的 active、pool size、queue size 和 reject數據庫連接池的 active、idle 與等待時間以及 HTTP 客戶端的連接獲取與進行中請求。每個指標都要帶池名稱不能把某個自定義executor.queued當成整個 Tomcat 或 WebFlux 的狀態。隊列長度必須結合處理速率。短時出現幾個等待任務未必有問題持續增長且完成速率跟不上入口才說明無法收斂。無界隊列不會顯示“滿”卻會讓內存和等待時間不斷增長因此配置巡檢還要確認隊列類型與容量。連接池達到上限時不要立刻調大。先看連接為何長期占用、超時是否生效、下游是否變慢。擴大每個實例的池后再乘以副本數可能超過數據庫或服務端能承受的總連接。第四層再進入 JVMJVM 巡檢關注堆、非堆、GC 暫停、分配速率、線程和類加載但沒有一條固定閾值適合所有服務。先建立當前 JDK、GC 和負載下的基線再看趨勢與用戶延遲是否同時變化。Metaspace 的max可能沒有配置成有限值此時簡單計算使用比例沒有意義。更值得觀察的是類加載數量、使用量是否在穩定流量下持續增長以及 Full GC 后能否回落。動態代理、腳本和頻繁創建類加載器只是可能原因需要結合 Heap Dump、類加載統計和版本變更驗證。GC 暫停也不能孤立解讀。記錄暫停分布、發生原因、堆占用和分配速率再與請求長尾對齊。偶發暫停不一定影響用戶持續高分配導致頻繁回收才需要繼續定位。Heap Dump 與線程 Dump 可能包含業務數據應限制觸發、訪問和保留時間。Actuator 數據先由監控系統統一采集Spring Boot Actuator 與 Micrometer 可以暴露運行指標但具體名稱、標簽和可用性取決于版本與已注冊組件。建立 Prometheus 等采集系統后日常巡檢優先查詢統一時序數據而不是額外腳本并發輪詢每個 Pod。后者會制造新負載也難以保留趨勢。小型環境確實需要只讀腳本時要把“指標缺失”與“指標為零”分開并保護 Actuator 入口。下面的示例只檢查健康狀態不打印響應正文服務地址來自受控配置超時和并發都有限。它不能替代認證、TLS 和集中監控。from concurrent.futures import ThreadPoolExecutor, as_completed from dataclasses import dataclass from typing import Literal import requests dataclass(frozenTrue) class Service: name: str base_url: str dataclass(frozenTrue) class Result: service: str status: Literal[UP, DOWN, UNKNOWN] reason: str def inspect(service: Service) - Result: try: response requests.get( f{service.base_url}/actuator/health/readiness, timeout(1, 2), ) if response.status_code ! 200: return Result(service.name, DOWN, fhttp_{response.status_code}) payload response.json() status payload.get(status) if status UP: return Result(service.name, UP, readiness_up) return Result(service.name, DOWN, readiness_not_up) except (requests.RequestException, ValueError) as exc: return Result(service.name, UNKNOWN, type(exc).__name__) def inspect_all(services: list[Service]) - list[Result]: with ThreadPoolExecutor(max_workersmin(4, len(services))) as executor: futures [executor.submit(inspect, service) for service in services] return [future.result() for future in as_completed(futures)]UNKNOWN不能顯示成綠色健康。網絡、認證或響應格式問題都需要單獨處理。腳本也不應自動重啟實例先保留證據再由有權限和審計的處置流程決定動作。告警與日報處理不同時間尺度需要立即通知的是正在影響用戶并且有人可以處理的狀態例如關鍵路徑持續失敗、隊列無法收斂或全部實例不可用。容量趨勢、Metaspace 增長和依賴版本偏差更適合進入日報或工單。把所有異常都發成電話告警只會消耗值班注意力。去重不應僅按Service Metric。同一根因可能讓幾十個服務同時報警應按依賴或調用拓撲聚合同一指標在不同集群又可能是兩起事件需要保留環境標簽。靜默規則設置開始、結束與負責人避免維護窗口結束后告警仍被永久壓制。每條告警附上當前值、基線、持續時間、受影響路徑和一條只讀排查入口。若接收人無法根據內容決定繼續觀察、限流或升級就應重新設計這條告警。巡檢本身也需要預算高頻、昂貴的管理查詢會影響被觀察系統。健康接口保持輕量指標由拉取系統按容量采集日志查詢限制時間和結果量。不要在業務高峰自動觸發 Heap Dump也不要讓巡檢賬號擁有修改配置或重啟服務的權限。定期演練指標缺失、注冊異常、線程池拒絕和下游超時確認告警能觸發、說明足夠、恢復條件明確。規則修改后先回放歷史數據檢查是否把已知波動重新變成噪聲。一套可用的巡檢順序應該讓值班人員從用戶影響走到具體資源再回到變更和依賴證據。它不追求指標最多而是盡快回答現在是否影響用戶問題在哪一層誰需要采取什么動作。