系統可觀測性

想象一下,有一天早上醒來,你發現腰帶上的最後一個洞塞不進去了。你走到體重秤前,發現一夜之間體重增加了很多。你開始緊急節食和健身。幾周後,看了看體重秤,發現自己的體重不知怎麼增加了更多。這是怎麼回事?

你需要了解的是你的身體正在發生什麼變化。如果我們的身體有內置可觀察性功能,我們的身體就會有指標,就可以在儀表盤上繪製激素水平。如果能看到我們的激素水平突然失衡,在所有條件都相同的情況下,可以推測激素失衡一定是根本原因。但是,由於無法看到發生了什麼變化,爲了查出問題所在需要做很多的改變,每種改變都有各自的效果。

我們讓系統可可觀測,這樣就可以提出問題深入瞭解系統,並調試意料之外的問題。這意味着我們可以解決以前沒有發生過的任意問題。接下來,我們將實現服務的可觀測,這樣我們就可以理解服務正發生什麼變化。

三類遙測數據

可觀測性是從外部輸出瞭解系統內部 (它的行爲和狀態) 的一種方式。我們使用指標 (metrics)、結構化日誌(logs) 和鏈路跟蹤 (trace) 作爲輸出,使我們的系統可觀察。雖然有三種類型的遙測數據,每一種都有自己的用途,我們將討論,它通常來自相同的事件。例如,每當 web 服務處理一個請求時,它可能會增加 “已處理請求” 指標,爲該請求發出日誌,並對請求鏈路進行跟蹤。

指標 (Metrics)

指標:度量隨時間變化的數據,例如失敗的請求數量或每個請求花費的時間。諸如此類的度量有助於定義服務級別。我們將使用指標來報告系統的運行狀況,觸發內部告警,並在看板上繪製圖形,以便一目瞭然地瞭解系統的運行情況。

因爲指標是數值類型數據,你可以逐漸降低分辨率,以減少存儲需求和查詢時間。例如,如果我們經營一家圖書出版公司,就會對每一本書的購買都有指標。爲了運送客戶的圖書,我們需要知道客戶的訂單,但是在交付了圖書並且通過了退貨政策之後,我們不再關心訂單。當我們對業務做分析時會存在很多的細節。最終,我們只需要季度收益就可以計算納稅、計算年增長率,並知道是否可以僱傭更多的編輯和作者來擴大業務。

有三類指標:

我們可以測量任何東西,那麼應該測量什麼數據呢?” 什麼指標將在您的系統上提供有價值的信號? 以下是谷歌提出的衡量系統狀態的四個黃金信號:

雖然大多數調試故事都是從參數開始的—要麼是通過警報,要麼是有人注意到看板上的異常—但都需要查看日誌和跟蹤,以瞭解有關問題的更多細節。讓我們接下來看看日誌。

結構化日誌

日誌描述系統中的事件。我們應該記錄任何可以幫助瞭解服務的事件。日誌能幫助我們排除故障、審計和配置文件,這樣我們就可以瞭解出了什麼問題以及爲什麼,誰運行了什麼操作,以及這些操作花費了多長時間。例如,gRPC 服務日誌可以記錄每個 RPC 調用:

{     "request_id": "f47ac10b-58cc-0372-8567-0e02b2c3d479",     "level": "info",     "ts": 1600139560.3399575,     "caller": "zap/server_interceptors.go:67",     "msg": "finished streaming call with code OK",     "peer.address": "127.0.0.1:54304",     "grpc.start_time": "2020-09-14T22:12:40-05:00",     "system": "grpc",     "span.kind": "server",     "grpc.service": "log.v1.Log",     "grpc.method": "ConsumeStream",     "peer.address": "127.0.0.1:54304",     "grpc.code": "OK",     "grpc.time_ns": 197740   }

在這個日誌中,我們可以看到調用者的 IP 地址、他們調用的服務和方法、調用是否成功以及請求花費了多長時間。在分佈式系統中,請求 ID 有助於拼湊由多個服務處理的請求的完整圖像。

這個 gRPC 日誌是一個 JSON 格式的結構化日誌。結構化日誌是一組格式一致的鍵值對,便於程序讀取。結構化日誌使我們能夠分離日誌捕獲、傳輸、持久化和查詢。例如,我們可以用 protobuf 捕獲和傳輸我們的日誌,然後用 Parquet 格式對其進行編碼,並將它們持久化到數據庫中。

我建議在像 Kafka 這樣的事件流平臺上收集結構化日誌,以便對日誌進行任意處理和傳輸。例如,可以將 Kafka 與 BigQuery 這樣的數據庫連接起來查詢日誌,同時將 Kafka 與 GCS 這樣的對象存儲連接起來維護歷史副本。

在日誌記錄太少和沒有調試問題所需的信息之間,或者日誌記錄太多,被太多的信息淹沒和錯過重要的東西之間,需要一個平衡。我建議對錯誤日誌記錄詳細,並減少無用的日誌。這樣一來,就不太可能缺少故障排除或審覈問題所需的信息。

鏈路追蹤 (trace)

跟蹤捕獲請求的生命週期,對請求流經系統時跟蹤請求。使用 Jaegar、Stackdriver、和 Lightstep 等用戶界面,可以直觀地表示請求在系統中花費的時間。在分佈式系統中,當請求在多個服務上被處理時,這尤其有用。

你可以用詳細信息標記鏈路追蹤,以更多地瞭解每個請求。一個常見的例子是用用戶 ID 標記每個跟蹤,這樣如果用戶遇到問題,您就可以輕鬆地找到他們的請求。

鏈路追蹤包括一個或多個跨度。它可以是父 / 子關係,也可以是兄弟姐妹關係。每個跨度表示請求執行的一部分。具體如何分割這些部分取決於你自己。通常跨所有服務端到端跟蹤請求,從服務的入口點開始到出口點結束。然後深入每個服務並跟蹤重要的方法調用。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/90L9mOKYtmmvA4MxkEXkdQ