如何使用 Prometheus 儀表化應用

我們已經知道了如何將應用的監控指標如何接入 Prometheus,但是如何在自己的應用程序中暴露監控指標呢?我們可以通過直接在應用中集成 metrics 指標數據,也可以單獨開發一個對應的 exporter 來暴露指標,或者根據需求編寫腳本推送到 pushgateway 網關生成監控指標,不過最好的方式是直接在應用程序中集成 Prometheus 監控指標數據。

接下來我們將來了解如何使用 Prometheus 客戶端庫來暴露監控指標,使用一個 Prometheus Go 客戶端庫來儀表化一個 Go 應用程序,直接在代碼中添加相關指標以獲取對應用程序的監控能力。

抓取指標

我們已經很清楚 Prometheus 是如何抓取監控指標的了,Prometheus 通過一個 HTTP 請求抓取監控目標,默認請求的端點名是 /metrics

監控目標通過發送每個被跟蹤的時間序列單個樣本,以及樣本的指標名稱、標籤集合和樣本值來響應每個指標的當前狀態。抓取到數據後 Prometheus 會存儲每個樣本,併爲其添加一個服務器端的時間戳,從而從單個抓取構建成一組時間序列。

此外我們再回顧下獲取的監控指標格式:

# HELP http_requests_total The total number of HTTP requests.
# TYPE http_requests_total counter
http_requests_total{method="post",code="200"} 1027
http_requests_total{method="post",code="400"}    3

# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
process_open_fds 15

# HELP http_request_duration_seconds A histogram of the request duration.
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.05"} 24054
http_request_duration_seconds_bucket{le="0.1"} 33444
http_request_duration_seconds_bucket{le="0.2"} 100392
http_request_duration_seconds_bucket{le="0.5"} 129389
http_request_duration_seconds_bucket{le="1"} 133988
http_request_duration_seconds_bucket{le="+Inf"} 144320
http_request_duration_seconds_sum 53423
http_request_duration_seconds_count 144320

# HELP rpc_duration_seconds A summary of RPC durations in seconds.
# TYPE rpc_duration_seconds summary
rpc_duration_seconds{quantile="0.01"} 3.102
rpc_duration_seconds{quantile="0.05"} 3.272
rpc_duration_seconds{quantile="0.5"} 4.773
rpc_duration_seconds{quantile="0.9"} 9.001
rpc_duration_seconds{quantile="0.99"} 76.656
rpc_duration_seconds_sum 5.7560473e+04
rpc_duration_seconds_count 2693

抓取目標只會暴露當前訪問的值,而不會暴露它所跟蹤數據所有的歷史指標,指標中的每一行(註釋除外)就是一個時間序列的樣本,每個序列在同一個抓取中只能出現一次,所以,儀表化應用只需要在內存中跟蹤其指標的當前狀態即可,不需要跟蹤或緩存任何歷史指標狀態。

客戶端庫

Prometheus 官方已經提供了一些語言的客戶端庫,包括 Go、Java、Python、Ruby,還有一些非官方的第三方客戶端庫,可以用來幫助我們在應用中集成 Prometheus 指標服務。使用這些庫我們可以創建和跟蹤不同類型的指標,反映服務當前的狀態,這些庫都允許我們創建和更新單獨的指標對象,將它們註冊到一個指標註冊中心,然後通過 HTTP 暴露該指標註冊中心,也就是我們常用的 metrics 接口。

Prometheus 的儀表化客戶端庫中包含不同的指標類型:countersgaugeshistograms 以及 summaries,和 Prometheus 中的指標類型對應,具體要使用哪種類型的指標取決於我們的實際情況。

根據不同的指標類型,在構建指標對象的時候需要提供不同的選項,比如在創建直方圖的時候需要指定存儲桶 bucket,而創建計數器的時候下不需要其他額外參數的。此外構造的指標對象還爲每種類型的指標暴露了不同的狀態更新方法,例如,計數器具有增加當前值的方法,但不會暴露將計數器設置爲任意值的方法,但是儀表盤是允許我們設置當前值的。

另外 Prometheus 的客戶端庫頁面 (https://prometheus.io/docs/instrumenting/clientlibs/) 上列出的所有官方庫的實現都考慮到了效率和併發安全問題:

所以我們是可以放心(當然也是推薦)使用官方提供的客戶端庫來儀表化我們的應用程序的。

跟蹤指標

當對一個系統或者服務進行儀表化的時候,儘量提供一些有意義的測量指標,業界有幾個比較著名的指導方針,可以幫助我們來理解在一個系統中應該添加哪些指標。

1.Google 的四大黃金指標

有 4 個來自 Google SRE 手冊的黃金指標,這 4 個指標主要針對應用程序或用戶部分。

2. 資源指標的 USE 方法

USEUtilization(使用率)Saturation(飽和度)Error(錯誤)的首字母組合,是 Netflix 的內核和性能工程師 Brendan Gregg 提出的,主要用於分析系統性能問題,可以指導用戶快速識別資源瓶頸及錯誤,主要可以考慮添加以下指標。

3. 請求服務系統的 RED 方法

RED 方法是 Weave Cloud 基於 Google 的 4 個黃金指標再結合 Prometheus 及 Kubernetes 容器實踐得出的方法論,特別適用於對雲原生應用以及微服務架構應用進行監控和度量。在四大黃金指標的原則下,RED 方法可以有效地幫助用戶衡量雲原生以及微服務應用下的用戶體驗問題。RED 方法主要關注以下 3 種關鍵指標。

一般來說,上述三大監控理論的最佳實踐是:在遵循 Google 四大黃金指標的前提下,對於在線系統,結合 RED 方法和緩存命中率方式進行監測;對於離線系統或者主機監控,以 USE 方法爲主進行監測;對於批處理系統,可以採用類似 Pushgateway 的形式進行監控。

當然這些指南並不能完全覆蓋我們的實際監控需求,但是對於我們在應用中添加哪些指標提供了一個很好的指導作用。Prometheus 官方文檔中關於儀表化的最佳實踐 (https://prometheus.io/docs/practices/instrumentation/) 提供了更多關於不同類型系統監控的建議。

指標命名

一個時間序列的指標名稱描述了被監測系統的某些狀態,比如在如下所示的時間序列中:

http_requests_total{job="nginx",instance="localhost:8080",method="POST"}

指標名稱就是標籤前面的 http_requests_total,該指標名稱本身字面意思就可以幫助我們理解該指標的含義了,雖然 Prometheus 本身並不會以語義方式解釋指標名稱。爲了幫助標準化指標命名,Prometheus 官方文檔上列出了建議遵循的指標命名最佳實踐(https://prometheus.io/docs/practices/naming/#metric-names)。

請注意,直方圖和摘要還生成帶有後綴 _sum_count_bucket(單個直方圖桶的計數器)的計數器指標,但這些是根據基本指標名稱自動生成的直方圖,因此我們不需要手動指定這些後綴。

一個給定指標的所有維度上的 sum()avg() 應該是有意義的(儘管不一定有用),如果沒有意義,請將數據拆分爲多個指標。例如,將各種隊列的容量放在一個指標中是可行的,而將一個隊列的容量與隊列中的當前元素數混合在一起則是不規範的。

標籤

我們知道 Label 標籤是 Prometheus 中非常重要的一個元素,在我們儀表化應用的時候爲指標指定合適的標籤也是非常重要的。我們知道每組唯一的標籤(包括指標名稱)都會標識並自動創建一個唯一的時間序列,Prometheus 會在查詢期間跟蹤、存儲和處理該時間序列,時間序列的數量也是 Prometheus 主要的性能瓶頸之一,對於稍好性能的服務器來說,通常可以很好的處理幾百萬的時間序列,當然最好不要太大,所以在決定將哪些標籤維度添加到指標中的時候,需要考慮到這一點。

Prometheus 總的時間序列成本需要通過指標上的不同標籤維度相乘得到,比如我們按照 status code 和 method 來拆分 HTTP 請求計數,則序列總數將是不同的 status code 和不同的 method 數量的乘積得到這兩個維度的所有有效組合,然後還需要將該基數乘以相同類型的受監控目標的數量,以得出 Prometheus 服務器的總體時間序列成本,所以對於標籤維度的控制是非常重要的,不能太少,也不能太多。

爲避免時間序列數量激增,請保持你的每個標籤的可能值的數量有一定的限制。尤其要避免以下示例:

這將迅速產生一個不斷增加的時間系列,在短時間內使 Prometheus 服務器過載,所以我們要避免用這種方式的標籤值。接下來我們將學習使用 Prometheus 的 Go 客戶端庫 (https://github.com/prometheus/client_golang) 來爲一個 Go 應用程序添加和暴露監控指標。

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