4.0.2 以監控鏈盤點單機短網址服務:各層現有的監控、缺口的性質與補法,以及監控鏈事前偵測不到的異常
這一篇拿 4.0 服務端監控的分層 的監控鏈盤點一個單機的短網址服務:把它現有的每一種監控放到所屬的層,逐層判讀還開著的缺口是哪一種、補它要加什麼。盤點用到四種缺口:檢查範圍盲區是沒有觀察者檢查那個對象,位置盲區是觀察者跟被觀察的元件共用一個依賴、那個依賴停掉時一起停,讀取缺口是觀察者有結果而沒有規則讀它、或通知送不出去,訊號失真是觀察者自己壞掉沒人知道、或規則的寫法讓結果不可信;完整的定義與例子在 4.0 的〈一層監控檢查的對象與它的缺口〉,盤點時的判讀依據在同一篇的〈以監控鏈盤點一個服務的判讀依據〉。服務的功能與需求見 Backend 範例系統 的〈短網址服務〉;對照的案例是 4.0.3 以監控鏈盤點 Kubernetes 上的電商 checkout,那個服務跑在叢集上、有佇列與第三方,失效域與缺口的分布都不同;撮合引擎單一執行緒、觀察者不能進處理路徑的系統,見 4.0.4 以監控鏈盤點交易撮合系統。
單機短網址服務現有的監控與各層的判讀
這個短網址服務的入口 Nginx、後端程式、PostgreSQL 與 Valkey 跑在同一台主機上,假設它接了容器健康檢查、同一台主機上的 Gatus(以 Gatus 自己的通知推播到手機)、Prometheus 與主機、容器、資料庫、快取與入口的 exporter、Alertmanager 推播到手機,以及跑在同一台主機上的心跳監看服務。判讀如下表:
| 監控鏈的層 | 這個服務現有的監控 | 判讀 |
|---|---|---|
| 容器與程序的自檢 | 每個容器的 Docker 健康檢查 | 讀取缺口:unhealthy 沒有程式讀它;症狀由 Gatus 的探測檢查,可記為接受,條件見表下 |
| 服務網路內的探測 | 同一台主機上的 Gatus,以自己的通知推播 | 訊號失真:Gatus 停掉時沒有人知道;讀取缺口:Gatus 的推播送不出去時沒有人知道(心跳只涵蓋告警鏈)。公開入口由使用者路徑那一層負責,該層目前沒有觀察者 |
| 元件指標 | Prometheus 與主機、容器、資料庫、快取、入口的 exporter | 已涵蓋 |
| 應用層訊號 | 沒有請求指標(只有 Gatus 量到的探測耗時);程式的 log 只在 docker logs 裡 | 檢查範圍盲區:每個端點的錯誤率與耗時分布沒有任何觀察者記錄;讀取缺口:log 裡的錯誤沒有程式讀它 |
| 告警規則與分送 | Prometheus 規則與 Alertmanager,推播到手機 | 已涵蓋 |
| 告警鏈的監看 | 心跳監看服務,跑在同一台主機上 | 位置盲區:心跳監看服務在檢查,而主機停掉時它跟著停 |
| 使用者路徑的合成監控 | 無 | 檢查範圍盲區:沒有探測走公開網址;補的觀察者要放在失效域以外,放在服務主機上的只補得上公開網域與 TLS 憑證這兩段,而且補上之後就有位置盲區 |
應用層與探測那幾列的缺口,補的是規則與指標;告警鏈的監看與使用者路徑那兩列,補的是觀察者的位置。自檢的讀取缺口可以補、也可以記為接受:要補時,加一個監聽 Docker health_status 事件的程式,把事件轉成通知;接受的理由是同一個症狀(服務沒有回應)已經由 Gatus 的探測檢查,只要 Gatus 的缺口補上,容器變成 unhealthy 時探測也會失敗。應用層訊號的檢查範圍盲區補的是逐端點的請求指標,由程式輸出,或由入口的存取紀錄換算;它的讀取缺口補的是一條讀 log 的規則。服務網路內的探測的訊號失真與讀取缺口,補的是讓 Prometheus 讀 Gatus 的指標、寫一條在讀不到 Gatus 的指標時成立的規則,並把探測失敗改由 Alertmanager 送出。告警鏈的監看是位置盲區,心跳的機制已經能運作,補的是一個失效域以外的位置,以及與告警鏈分開、不經過服務主機的通知管道;監看要證明的另一件事是通知送得出去,這個服務的 Prometheus 規則若還沒有以 alertmanager_notifications_failed_total 寫的送失敗規則,要一起補上,送到同一個心跳監看服務的另一個檢查項目。使用者路徑是檢查範圍盲區,而它的補法同時決定位置:在服務主機上加一條走公開網址的探測,公開網域的解析與 TLS 憑證在它的路徑上,而主機對外的防火牆與業者的網路不一定在(主機連自己的公開位址時,封包可能不出主機),主機停掉時這條探測也跟著停;補上整個檢查範圍盲區而不留位置盲區的,是失效域以外的合成監控服務或另一台主機。失效域以外的觀察者補上之前,主機整台停掉這個故障沒有任何一層會通知,那時第一個發現的會是使用者,客訴怎麼接進事故流程見 4.25 觀測共命運失效。
監控鏈事前偵測不到的異常:逐類查單機短網址服務
4.0.1 監控鏈事前偵測不到的異常 那幾類,與監控鏈的各層分開逐類查。這個服務的業務結果(每 10 分鐘新建的短網址數)、資料正確性(轉址目標與建立時寫入的一致)、安全(使用者登入、管理者停用短網址與查看帳號的稽核紀錄)與成本(主機業者的帳單告警)都沒有人監看;它沒有呼叫第三方、也沒有佇列,第三方依賴與佇列的消費端不適用。憑證與網域到期要一條走公開網址的探測:讓 Gatus 對公開網域加一條探測並設 [CERTIFICATE_EXPIRATION] 與 [DOMAIN_EXPIRATION] 條件,或加 blackbox_exporter 的一條規則;網域到期也會讓寄到這個網域信箱的通知一起收不到。這條探測從服務主機發出,檢查的是使用者路徑那一層的對象之一(憑證),而它和服務共用失效域;憑證到期是事前的預警,主機正常時它就能送出,所以放在服務主機上仍有用。每晚的資料庫備份是工作完成時對心跳監看服務送一次心跳;備份的心跳送到同一個心跳監看服務,所以它和告警鏈的心跳有同樣的位置盲區:主機停掉時兩種心跳都沒人收,把心跳監看服務搬到失效域以外,兩者一起補上。
單機服務的缺口分布與服務組成的關係
這張表的缺口分成三群:失效域以外沒有觀察者(告警鏈的監看、使用者路徑),沒有人讀的結果(自檢的 unhealthy、Gatus 的推播、log 裡的錯誤),以及應用層沒有逐端點的請求指標。失效域以外沒有觀察者是所有觀察者都在同一台主機上的結果,失效域就是那一台主機;服務搬上叢集之後,失效域換成整個叢集、雲端帳號與區域,失效域以外的觀察者要放到哪裡也跟著改變,見 4.0.3 以監控鏈盤點 Kubernetes 上的電商 checkout。沒有人讀的結果在單機上靠幾條規則就補得上,因為元件少、讀取的對象少;應用層的請求指標要改程式或換算入口的存取紀錄,是這三群裡唯一要動到服務本身的。