Prometheus Java 用戶端指南
一、簡介
隨著分散式系統變得越來越複雜,監控對於維護應用程式效能和快速識別問題變得至關重要。最好的工具之一是Prometheus ,這是一個強大的開源監控和警報工具包。
Prometheus Java 用戶端讓我們可以透過公開即時指標供 Prometheus 抓取和監控,以最少的努力來檢測我們的應用程式。
我們將探索如何將 Prometheus Java 用戶端程式庫與 Maven 結合使用,包括建立自訂指標並配置 HTTP 伺服器來公開它們。此外,我們將介紹該程式庫提供的不同指標類型,並提供將所有這些元素連結在一起的實際範例。
2. 設定項目
為了開始使用 Prometheus Java 用戶端,我們將使用 Maven 來管理專案的依賴項。我們需要將幾個基本依賴項新增到pom.xml
檔案中,以啟用 Prometheus 指標收集和公開:
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>prometheus-metrics-core</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>prometheus-metrics-instrumentation-jvm</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>prometheus-metrics-exporter-httpserver</artifactId>
<version>1.3.1</version>
</dependency>
我們使用以下相依性prometheus-metrics-core
是 Prometheus Java 用戶端的核心函式庫。它為定義和註冊自訂指標(例如計數器、儀表、直方圖等)提供了基礎。
prometheus-metrics-instrumentation-jvm
提供開箱即用的 JVM 指標,包括堆疊記憶體使用量、垃圾收集時間、執行緒計數等。
prometheus-metrics-exporter-httpserver
提供嵌入式 HTTP 伺服器,以 Prometheus 格式公開指標。它創建一個/metrics
端點,Prometheus 可以抓取該端點來收集資料。
3. 建立和公開 JVM 指標
本節將介紹如何透過 Prometheus Java 用戶端公開可用的 JVM 指標。這些指標為我們應用程式的效能提供了寶貴的見解。由於prometheus-metrics-instrumentation-jvm
依賴項,我們可以輕鬆註冊開箱即用的 JVM 指標,而無需自訂檢測:
public static void main(String[] args) throws InterruptedException, IOException {
JvmMetrics.builder().register();
HTTPServer server = HTTPServer.builder()
.port(9400)
.buildAndStart();
System.out.println("HTTPServer listening on http://localhost:" + server.getPort() + "/metrics");
Thread.currentThread().join();
}
為了使 JVM 指標可供 Prometheus 使用,我們透過 HTTP 端點公開它們。我們使用prometheus-metrics-exporter-httpserver
依賴項來設定一個簡單的 HTTP 伺服器,該伺服器偵聽連接埠並提供指標。
我們使用join()
方法來保持主執行緒無限期運行,確保 HTTP 伺服器保持活動狀態,以便 Prometheus 可以隨著時間的推移不斷抓取指標。
3.2.測試應用程式
應用程式運行後,我們可以打開瀏覽器並導航到http://localhost:9400/metrics
以查看公開的指標,或者我們可以使用curl
命令從命令列取得和檢查指標:
$ curl http://localhost:9400/metrics
我們應該會看到 Prometheus 格式的 JVM 相關指標列表,類似於:
# HELP jvm_memory_bytes_used Used bytes of a given JVM memory area.
# TYPE jvm_memory_bytes_used gauge
jvm_memory_bytes_used{area="heap",} 5242880
jvm_memory_bytes_used{area="nonheap",} 2345678
# HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds.
# TYPE jvm_gc_collection_seconds summary
jvm_gc_collection_seconds_count{gc="G1 Young Generation",} 5
jvm_gc_collection_seconds_sum{gc="G1 Young Generation",} 0.087
...
輸出顯示各種 JVM 指標,例如記憶體使用情況、垃圾收集詳細資訊和執行緒計數。 Prometheus 收集並分析這些指標,這些指標採用其專用的展示格式。
4. 指標類型
在 Prometheus Java 用戶端中,指標被分為不同的類型,每種類型在測量應用程式行為的各個方面都有特定的目的。這些類型是基於 Prometheus 遵守的OpenMetrics 標準。
讓我們探討 Prometheus Java 用戶端中可用的主要指標類型以及它們的典型使用方式。
4.1. Counter
Counter
是一種僅隨時間增加的指標。我們可以使用它們來計算收到的請求、遇到的錯誤或完成的任務。計數器不能減少,它們的值僅在進程重新啟動時重置。
我們可以計算應用程式處理的 HTTP 請求總數:
Counter requestCounter = Counter.builder()
.name("http_requests_total")
.help("Total number of HTTP requests")
.labelNames("method", "status")
.register();
requestCounter.labelValues("GET", "200").inc();
我們使用labelNames
和labelValues
為我們的指標添加維度或上下文。 Prometheus 中的標籤是鍵值對,使我們能夠區分相同指標的不同類別。
4.2. Gauge
Gauge
是一種可以隨時間增加或減少的指標。我們可以使用它們來追蹤隨時間變化的值,例如記憶體使用情況、溫度或活動線程數。
為了測量當前的記憶體使用情況或 CPU 負載,我們可能會使用一個儀表:
Gauge memoryUsage = Gauge.builder()
.name("memory_usage_bytes")
.help("Current memory usage in bytes")
.register();
memoryUsage.set(5000000);
4.3. Histogram
Histogram
通常用於觀察和追蹤值隨時間的分佈,例如請求延遲或回應大小。它記錄預先配置的儲存桶,並提供有關每個儲存桶中的觀察數、總計數以及所有觀察值總和的指標。這使我們能夠了解資料分佈並計算百分位數或範圍。
讓我們來看看一個詳細的範例,該範例測量 HTTP 請求持續時間並使用自訂儲存桶來追蹤特定範圍的回應時間:
Histogram requestLatency = Histogram.builder()
.name("http_request_latency_seconds")
.help("Tracks HTTP request latency in seconds")
.labelNames("method")
.register();
Random random = new Random();
for (int i = 0; i < 100; i++) {
double latency = 0.1 + (3 * random.nextDouble());
requestLatency.labelValues("GET").observe(latency);
}
創建直方圖時我們沒有指定任何自訂儲存桶,因此庫使用一組預設儲存桶。預設儲存桶涵蓋指數範圍的值,適合許多測量持續時間或延遲的應用程式。具體來說,預設的桶邊界如下:
[5ms, 10ms, 25ms, 50ms, 100ms, 250ms, 500ms, 1s, 2.5s, 5s, 10s, +Inf]
檢查結果時,我們可能會看到以下輸出:
http_request_latency_seconds_bucket{method="GET",le="0.005"} 0
http_request_latency_seconds_bucket{method="GET",le="0.01"} 0
http_request_latency_seconds_bucket{method="GET",le="0.025"} 0
http_request_latency_seconds_bucket{method="GET",le="0.05"} 0
http_request_latency_seconds_bucket{method="GET",le="0.1"} 0
http_request_latency_seconds_bucket{method="GET",le="0.25"} 6
http_request_latency_seconds_bucket{method="GET",le="0.5"} 15
http_request_latency_seconds_bucket{method="GET",le="1.0"} 32
http_request_latency_seconds_bucket{method="GET",le="2.5"} 79
http_request_latency_seconds_bucket{method="GET",le="5.0"} 100
http_request_latency_seconds_bucket{method="GET",le="10.0"} 100
http_request_latency_seconds_bucket{method="GET",le="+Inf"} 100
http_request_latency_seconds_count{method="GET"} 100
http_request_latency_seconds_sum{method="GET"} 157.8138389516349
每個桶顯示有多少觀測值屬於該範圍。例如, http_request_duration_seconds_bucket{le=”0.25″}
表示 6 個請求所花費的時間小於或等於 250ms。 +Inf
儲存桶捕獲所有觀測值,因此它的計數是觀測值的總數。
4.4. Summary
Summary
類似於Histogram
,但它不使用預先定義的儲存桶,而是計算分位數來總結觀察到的資料。因此,它對於追蹤請求延遲或回應大小變得非常有用。此外,它還幫助我們確定關鍵指標,例如中位數(第 50 個百分位數)或第 90 個百分位數:
Summary requestDuration = Summary.builder()
.name("http_request_duration_seconds")
.help("Tracks the duration of HTTP requests in seconds")
.quantile(0.5, 0.05)
.quantile(0.9, 0.01)
.register();
for (int i = 0; i < 100; i++) {
double duration = 0.05 + (2 * random.nextDouble());
requestDuration.observe(duration);
}
我們定義兩個分位數:
- 0.5(第 50 個百分位數)近似於中位數,誤差為 5%。
- 0.9(第 90 個百分位數)表示 90% 的請求比該值快,有 1% 的錯誤。
當 Prometheus 抓取指標時,我們將看到以下輸出:
http_request_duration_seconds{quantile="0.5"} 1.3017345289221114
http_request_duration_seconds{quantile="0.9"} 1.8304437814581778
http_request_duration_seconds_count 100
http_request_duration_seconds_sum 110.5670284649691
分位數顯示第 50 個和第 90 個百分位數的觀測值。換句話說,50% 的請求花費的時間少於 1.3 秒,90% 的請求花費的時間少於 1.9 秒。
4.5. Info
Info
指標儲存有關應用程式的靜態標籤。它用於版本號、建置資訊或環境詳細資訊。它不是一個效能指標,而是一種向 Prometheus 輸出添加資訊元資料的方法。
Info appInfo = Info.builder()
.name("app_info")
.help("Application version information")
.labelNames("version", "build")
.register();
appInfo.addLabelValues("1.0.0", "12345");
4.6. StateSet
StateSet
度量表示多個狀態,可以是活動的,也可以是非活動的。當我們需要追蹤應用程式的不同操作狀態或功能標誌狀態時,它非常有用:
StateSet stateSet = StateSet.builder()
.name("feature_flags")
.help("Feature flags")
.labelNames("env")
.states("feature1")
.register();
stateSet.labelValues("dev").setFalse("feature1");
5. Prometheus Metric 類型概述
Prometheus Java 用戶端提供了各種指標來捕捉應用程式效能和行為的不同維度。以下是一個總計表,概述了每種指標類型的主要功能,包括其目的和使用範例:
公制類型 | 描述 | 範例用例 |
---|---|---|
Counter |
僅隨著時間的推移而增加的指標,通常用於對事件進行計數 | 計算 HTTP 請求或錯誤的數量 |
Gauge |
它可以增加或減少,用於隨時間波動的值 | 追蹤記憶體使用情況或活動線程數 |
Histogram |
測量值到可配置桶中的分佈 | 觀察請求延遲或回應大小 |
Summary |
追蹤觀測值的分佈並計算可配置的分位數 | 測量請求持續時間或延遲百分位數 |
Info |
儲存帶有有關應用程式的元資料的靜態標籤 | 捕獲版本或建置訊息 |
StateSet |
追蹤多個活動或非活動的操作狀態 | 監控功能標誌狀態 |
六、結論
在本文中,我們探討如何透過偵測自訂指標和 JVM 指標,有效地使用 Prometheus Java 用戶端來監控應用程式。首先,我們介紹了使用 Maven 依賴項設定項目。因此,我們繼續透過 HTTP 端點公開指標。隨後,我們討論了關鍵指標類型,例如計數器、儀表、直方圖和摘要,每種類型在追蹤各種效能指標方面都有不同的用途。
與往常一樣,本文的完整實作程式碼可以在 GitHub 上找到。