基于關鍵的可觀測性指標了解應用服務運行狀態,能夠提升服務運行效能。本文分析了分布式應用的 4 個核心可觀測性指標。
基于關鍵的可觀測性指標,我們更能了解我們的應用服務運行狀態,以便提升服務運行效能。
如今,一種最為流行的架構設計模式便是將應用程序單體分解為更小的微服務。然后,每個微服務負責應用程序的特定方面或功能。例如,一個微服務可能負責提供外部 API 請求,而另一個可能處理前端的數據獲取。
以這種方式設計一個強大且故障安全的基礎設施可能具有挑戰性;一起監控所有這些微服務的操作可能更加困難。最好不要簡單地依靠應用程序日志來了解系統的成功和錯誤。設置適當的監控將為我們提供更完整的觀測圖,但可能很難知道從哪里開始。在這篇文章中,我們將介紹可觀測性指標應該關注的那些服務領域,以確保大家不會錯過關鍵信息。
在開始本文內容之前, 我們將對所運行的應用程序設置做一些假設。我們不需要使用任何特定框架來開始跟蹤指標,但是,它確實有助于對所涉及的組件有一個大致的了解。換句話說,你如何設置你的可觀察性工具比你跟蹤什么更重要。
由于足夠大的微服務集需要某種程度的協調,我們將假設使用 Kubernetes 進行編排。我們還假設有一個時間序列數據庫,如 Prometheus 或 InfluxDB,用于存儲我們的指標數據。同時,我們可能還需要一個入口控制器(例如 Kong 提供的用于控制流量的控制器)和服務網格(例如 Kuma)以更好地促進服務之間的連接。
在實施任何監控之前,必須了解我們的應用服務實際上如何進行相互交互。編寫一份文檔,確定哪些服務和功能相互依賴,以及可用性問題將如何影響它們,可以幫助我們制定戰略,圍繞為構成適當閾值的內容設置基線數字。
指標類型
我們應該能夠從兩個角度查看數據點:影響數據和因果數據。影響數據表示識別誰受到影響的信息。例如,如果服務中斷并且響應變慢,Impact Data 可以幫助確定受影響的活躍用戶的百分比。
Impact Data 確定誰受到影響,Causal Data 確定受影響的對象及其原因。Kong Ingress 可以監控網絡活動,可以讓我們深入了解影響數據。同時,Kuma 可以收集和報告因果數據。
讓我們看一下幾個數據源,并探索可以收集到的影響數據和因果數據之間的差異。
1、延遲
延遲是用戶執行操作與其最終結果之間所花費的時間。例如,如果用戶將一件商品添加到他們的購物車中,則延遲將衡量從添加商品到用戶看到表明添加成功的響應之間的時間。如果負責執行此操作的服務降級,則延遲會增加,并且如果沒有立即響應,用戶可能會懷疑該站點是否正在運行。
為了在影響數據上下文中正確跟蹤延遲,有必要在整個生命周期中跟蹤單個事件。繼續我們的采購示例,我們可能希望事件的完整流程如下所示:
客戶點擊“加入購物車”按鈕
瀏 覽器發起服務器端請求,發起事件
服務器接受請求
數據庫查詢確保產品仍有庫存
解析數據庫響應,向用戶發送響應,事件完成
要成功地遵循此順序,我們應該標準化一個命名模式,以標識正在發生的事情和發生的時間,例如 customer_purchase.initiate、customer_purchase.queried、customer_purchase.finalized 等。基于所采用的編程語言,我們可能能夠為指標服務提供功能塊或 lambda:
statsd.timing('customer_purchase.initiate') do# ...end
通過提供特定的關鍵字,我們應該確定在出現延遲問題時事件的哪個部分變慢。
跟蹤因果數據上下文中的延遲需要我們跟蹤服務之間事件的速度,而不僅僅是執行的操作。實際上,這意味著定時服務到服務請求:
statsd.histogram('customer_purchase.initiate') dostatsd.histogram('customer_purchase.external_database_query') do# ...endend
這不應僅限于捕獲整個端點請求/響應周期。這種延遲跟蹤太廣泛了,應該更細化。假設我們有一個帶有發出內部數據庫請求的端點的微服務。在這種情況下,我們可能希望計算收到請求的時間、查詢花費的時間、服務響應請求的時間以及原始客戶端收到該請求的時間。通過這種方式,我們可以精確地確定服務如何相互通信。
2、流量
如果希望我們的應用程序有用且受歡迎——但此時,我們還沒有做好準備,大量用戶涌入可能是一件好事!網站流量的變化很難預測。我們可能能夠每天為用戶負載提供服務,但事件(預期的和意外的)可能會產生意想不到的后果。我們的電子商務網站是否在進行周末促銷?我們的網站是否因為一些意外的贊美而走紅?流量差異也會受到地理位置的影響。也許日本用戶正在以一種法國用戶沒有的方式體驗流量負載。我們可能認為我們的系統正在按預期工作,但所需要的只是大量用戶涌入來測試這種信念。如果一個事件需要 200 毫秒才能完成,但我們的系統一次只能處理一個事件,那么看起來似乎沒有問題——直到事件隊列突然被工作堵塞為止。
與延遲類似,跟蹤整個事件生命周期中正在處理的事件數量以了解任何瓶頸很有用。例如,跟蹤隊列中的作業數、每秒完成的 HTTP 請求數和活動用戶數是監控流量的良好起點。
對于因果數據,監控流量涉及捕獲服務如何相互傳輸信息,類似于我們如何處理延遲。我們的監控設置應該跟蹤對特定服務的請求數量、它們的響應代碼、它們的有效負載大小等——盡可能多地了解請求和響應周期。當我們需要調查惡化的性能時,了解哪個服務遇到問題將有助于我們更快地跟蹤可能的來源。
3、錯誤率
跟蹤錯誤率相當簡單。我們的服務器作為 HTTP 響應發出的任何 5xx(甚至 4xx)都應該被標記和計數。即使我們已經考慮到的情況,例如捕獲的異常,也應該受到監視,因為它們仍然代表非理想狀態。這些問題可以作為防御性編碼產生的更深層次問題的警告,這些問題沒有解決實際問題。
Kuma 可以捕獲我們的服務拋出的錯誤代碼和消息,但這僅代表可操作數據的一部分。例如,我們還可以捕獲導致錯誤的參數(萬一查詢格式錯誤)、發出的數據庫查詢(萬一超時)、執行用戶的權限(萬一他們進行了未經授權的嘗試)、等等。簡而言之,捕獲產生錯誤時的服務狀態可以幫助我們在開發和測試環境中復制問題。
4、飽和度
除此之外,我們還應該跟蹤每個微服務的內存使用情況、CPU 使用情況、磁盤讀/寫和可用存儲。如果我們服務的資源使用在某些時間或操作期間經常激增或以穩定的速度增加,則表明應用服務過度使用了服務器資源。雖然服務器可能按預期運行,但再次涌入的流量或其他不可預見的事件可能會迅速推翻它。
Kong Ingress 只監控網絡活動,因此不太適合跟蹤飽和度。但是,有許多工具可用于使用 Kubernetes 進行跟蹤。
實施監控和可觀察性
到目前為止,我們已經討論了在云應用程序中跟蹤很重要的指標類型。接下來,讓我們深入了解我們可以采取的一些具體步驟來實現這種監控和可觀察性。
1、安裝 Prometheus
Prometheus 是監控的首選標準,是一個易于安裝并與 Kubernetes 設置集成的開源系統。如果基于 Helm 部署,則安裝會特別簡單。
首先,我們創建一個監控命名空間:
[administrator@JavaLangOutOfMemory ~] % kubectl create namespace monitoring
接下來,我們使用 Helm 安裝 Prometheus。我們確保也將 Prometheus 圖表添加到 Helm:
[administrator@JavaLangOutOfMemory ~] % helm repo add prometheus-community [administrator@JavaLangOutOfMemory ~] % helm repo add stable [administrator@JavaLangOutOfMemory ~] % helm repo update[administrator@JavaLangOutOfMemory ~] % helm install -f -n monitoring prometheus prometheus-community/prometheus
中引用的值文件將 Prometheus 的數據抓取間隔設置為 10 秒。
2、在 Kong 中啟用 Prometheus 插件
假設正在為 Kubernetes 使用 Kong Ingress Controller (KIC),我們的下一步將是創建一個自定義資源——KongPlugin 資源——它集成到 KIC 中。創建一個名為 prometheus-plugin.yml 的文件:
apiVersion: configuration.konghq.com/v1kind: KongClusterPluginmetadata:name: prometheusannotations:kubernetes.io/ingress.class: konglabels:global: "true"plugin: prometheus
3、安裝 Grafana
Grafana 是一個可觀察性平臺,它為 Prometheus 抓取的數據的可視化提供了出色的儀表板。我們使用 Helm 安裝 Grafana 如下:
administrator@JavaLangOutOfMemory ~ % helm install grafana stable/grafana -n monitoring --values
我們可以查看上述命令中的 bit.ly URL,以查看我們在安裝時提供的 Grafana 的具體配置值。
4、啟用端口轉發
現在 Prometheus 和 Grafana 在我們的 Kubernetes 集群中啟動并運行,我們需要訪問他們的儀表板。在本文中,我們將設置基本端口轉發以公開這些服務。這是一種簡單但不是很安全的訪問方式,但不建議用于生產部署。
[administrator@JavaLangOutOfMemory ~] % POD_NAME=$(kubectl get pods --namespace monitoring -l "app=prometheus,component=server" -o jsonpath="{.items[0].metadata.name}")kubectl --namespace monitoringport-forward $POD_NAME 9090 &[administrator@JavaLangOutOfMemory ~] % POD_NAME=$(kubectl get pods --namespace monitoring -l "app.kubernetes.io/instance=grafana" -o jsonpath="{.items[0].metadata.name}")kubectl --namespace monitoring port-forward $POD_NAME 3000 &
以上兩個命令在端口 9090 上公開 Prometheus 服務器,在端口 3000 上公開 Grafana 儀表板。
這些簡單的步驟應該足以讓其開始運行。使用 Kong Ingress Controller 及其集成的 Prometheus 插件,使用 Prometheus 捕獲指標并使用 Grafana 將它們可視化設置起來既快速又簡單。
結論
每當我們需要調查惡化的性能時,我們的影響數據指標都可以幫助我們確定問題的嚴重程度:它應該告訴我們有多少人受到影響。同樣,我們的因果數據確定什么不起作用以及為什么。前者將我們指向一縷煙,后者將我們 指向火。
除了上述所有因素外,我們還應該考慮指標變化的速度。例如,假設我們的流量數字正在增加。觀察這些數字的變化速度可以幫助我們確定何時(或是否)它會成為問題。這對于通過定期部署和服務更改來管理即將進行的工作至關重要。它還確定了理想的性能指標應該是什么。
Google 寫了整本關于站點可靠性的書,這是任何開發人員的必讀之書。如果我們已經在集群旁邊運行 Kong,那么像這樣的插件直接與 Prometheus 集成,這意味著我們可以減少用于監控和存儲服務指標的配置。
【作者】李杰,專注于Java虛擬機技術、云原生技術領域的探索與研究。