Micrometer:Spring Boot 2 全新的應用程式指標收集器

工程 | Jon Schneider | 2018 年 3 月 16 日 | ...

目錄

它是什麼?

Micrometer 是一個以維度優先的指標收集外觀模式,其目標是讓您使用與供應商無關的 API 來計時、計數和衡量您的程式碼。透過類別路徑和組態,您可以選擇一個或多個監控系統來匯出您的指標資料。可以將其視為指標界的 SLF4J!

Micrometer 是 Spring Boot 2 的 Actuator 中包含的指標收集工具。它也已向後移植到 Spring Boot 1.5、1.4 和 1.3,只需新增另一個相依性即可。

Micrometer 為 Spring Boot 1 中已存在的計數器和量表新增了更豐富的儀表基本元件。例如,單個 Micrometer Timer 能夠產生與吞吐量、總時間、最近樣本的最大延遲、預先計算的百分位數、百分位數直方圖和 SLA 邊界計數相關的時間序列。

An Kibana-rendered timer

儘管 Micrometer 專注於維度指標,但它確實會對應到階層式名稱,以繼續為較舊的監控解決方案(如 Ganglia)或範圍較窄的工具(如 JMX)提供服務。改用 Micrometer 源於希望更好地服務於一波維度監控系統(例如 Prometheus、Datadog、Wavefront、SignalFx、Influx 等)。Spring 的優勢之一是透過抽象化實現選擇。透過與 Micrometer 整合,Spring Boot 使您能夠選擇一個或多個監控系統在今天使用,並在日後隨著需求變化而改變主意,而無需重寫您的自訂指標儀器。

在選擇開發「另一個」指標收集函式庫之前,我們仔細研究了現有或正在興起的維度收集器。但是,隨著我們考慮匯出到越來越多的監控系統,名稱和資料結構的重要性變得顯而易見。Micrometer 內建了命名慣例標準化、時間基本單位縮放以及對直方圖資料等結構的專有表示形式的支援等概念,這些對於使指標在每個目標系統中發光至關重要。一路上,我們也新增了儀表過濾,讓您可以更精確地控制上游相依性的儀器。

提示

若要瞭解有關 Micrometer 功能的更多資訊,請參閱其參考文件,特別是概念章節

我可以從中獲得什麼開箱即用的功能?

Spring Boot 2 自動配置了相當多的指標供您使用,包括

  • JVM,報告使用率,包括

    • 各種記憶體和緩衝區池

    • 與垃圾回收相關的統計資訊

    • 執行緒使用率

    • 載入/卸載的類別數量

  • CPU 使用率

  • Spring MVC 和 WebFlux 請求延遲

  • RestTemplate 延遲

  • 快取使用率

  • 資料來源使用率,包括 HikariCP 池指標

  • RabbitMQ 連線工廠

  • 檔案描述器使用率

  • Logback:記錄在每個層級記錄到 Logback 的事件數量

  • 正常運作時間:報告正常運作時間的量表和代表應用程式絕對啟動時間的固定量表

  • Tomcat 使用率

這些指標中的許多指標在 Spring Boot 1 中以某種形式存在,但在 Spring Boot 2 中已透過更詳細的資訊和標籤得到豐富。

Micrometer 支援哪些監控系統?

Micrometer 提供與供應商無關的指標收集 API(根植於 io.micrometer.core.instrument.MeterRegistry)以及各種監控系統的實作

  • Netflix Atlas

  • CloudWatch

  • Datadog

  • Ganglia

  • Graphite

  • InfluxDB

  • JMX

  • New Relic

  • Prometheus

  • SignalFx

  • StatsD(Etsy、dogstatsd、Telegraf 和專有格式)

  • Wavefront

對其他系統的支援正在進行中或計劃在 2018 年年中發布的 1.1.0 版本中推出

  • AppOptics

  • Azure Application Insights

  • Dynatrace

  • Elasticsearch

  • StackDriver

Spring Boot 2 配置了一個複合 MeterRegistry,可以向其中新增任意數量的登錄檔實作,讓您可以將指標傳送到多個監控系統。透過 MeterRegistryCustomizer,您可以自訂整組登錄檔或特定的個別實作。例如,常見的請求設定是 (1) 將指標匯出到 Prometheus 和 CloudWatch,(2) 將一組通用標籤新增到流向兩者的指標(例如,主機和應用程式識別標籤),以及 (3) 將雲端監控 (CloudWatch) 的指標僅列入一小部分白名單。

指標與追蹤之間的區別

我們所說的指標,特別是指允許您推斷系統整體效能(跨單個應用程式的不同組件、叢集中應用程式的實例、在不同環境或區域中運作的叢集等)的那類資訊。

值得注意的是,這不包括旨在推斷各個組件對單個請求在通過一系列服務時的總延遲貢獻的資訊;這是分散式追蹤收集器(如 Spring Cloud Sleuth、Zipkin 的 Brave 等)的責任。

分散式追蹤系統提供有關子系統延遲的詳細資訊,但通常會為了擴展而進行降採樣(例如,Spring Cloud Sleuth 預設傳送 10% 的樣本)。指標資料通常是預先聚合的,因此自然缺乏相關資訊,但不會進行降採樣。因此,對於一分鐘間隔內的一系列 100,000 個請求,這些請求具有與服務 A 的互動,並且根據輸入,可能與服務 B 進行互動

  1. 指標資料會告訴您,總體而言,服務 A 的觀察到的吞吐量為 10 萬個請求,服務 B 的觀察到的吞吐量為 6 萬個請求。此外,在那一分鐘內,服務 A 的最大整體平均延遲為 100 毫秒,服務 B 的最大整體平均延遲為 50 毫秒。它還將提供有關該期間最大延遲和其他分佈統計資訊。

  2. 分散式追蹤系統會告訴您,對於特定請求(但不是所有請求,因為請記住正在進行降採樣),服務 A 花費了 50 毫秒,服務 B 花費了 90 毫秒。

您可能會合理地從指標資料中推斷出,最壞情況的使用者體驗中大約一半的時間花費在 A 和 B 中,但您無法確定,因為您正在查看聚合資料,並且完全有可能在最壞情況下,所有 100 毫秒都花費在服務 A 中,而根本沒有呼叫服務 B。

相反,從追蹤資料中,您無法推斷出某個間隔內的吞吐量或最壞情況的使用者體驗。

維度的重要性

Spring Boot 1 的指標介面本質上是階層式的。這表示發布的指標完全由其名稱識別。因此,您可能有一個名為 jvm.memory.used 的指標。

當您查看來自單個應用程式實例的指標時,這似乎很合適。但是,如果您有 10 個實例都將 jvm.memory.used 發布到同一個監控系統怎麼辦?如果一個實例上的記憶體消耗意外飆升,我們如何區分它們?

答案通常是將前綴或後綴新增到名稱中來擴充名稱。因此,我們可能會將名稱變更為 ${HOST}.jvm.memory.used,其中我們將 ${HOST} 替換為主機名稱。在重新部署所有 10 個實例後,我們現在可以識別哪個實例正在承受記憶體壓力。在典型的階層式監控系統中,我們可以透過以某種方式對名稱進行萬用字元化來推斷所有實例中使用的記憶體總和

*.jvm.memory.used

假設現在我們在 3 個部署區域中的每個區域都有 10 個應用程式實例。此外,我們希望推斷應用程式按區域劃分的平均或最大記憶體佔用量。現在,如果我們在指標名稱中新增額外的前綴(使其看起來像 ${REGION}.${HOST}.jvm.memory.used),我們就破壞了現有的查詢。我們可以更新查詢以推斷所有實例中使用的記憶體總和

*.*.jvm.memory.used

遺憾的是,這會讓我們在現有基礎架構上看不到任何內容,直到所有基礎架構都已使用新的前綴重新部署為止。這只是階層式命名方法的一個限制範例。

我們已經提到 Micrometer 是一個以維度優先的指標收集器。Micrometer 中的相同指標將使用標籤(也稱為維度)記錄

Gauge.builder("jvm.memory.used", ..)
  .tag("host", "MYHOST")
  .tag("region", "us-east-1")
  .register(registry);

維度監控系統自然會在所有標籤中以彙總方式顯示 jvm.memory.used,直到您深入到其中一個或多個標籤。維度監控系統中的查詢將首先選擇名稱 (jvm.memory.used),並允許隨後按標籤進行篩選。在我們上面的情境中,如果我們有一個基於主機記憶體消耗激增的現有圖表/警示,然後稍後為區域新增了一個額外的標籤,則基於主機的查詢將繼續不間斷地運作,因為新的包含區域資訊的指標已在您的基礎架構中推出。

儀表過濾器

儀表過濾器可讓您控制儀表的註冊方式和時間,以及它們發出的統計資訊類型。儀表過濾器提供三個基本功能

  • 拒絕(或接受)註冊儀表。

  • 轉換儀表 ID(例如,變更名稱、新增或移除標籤、變更描述或基本單位)。

  • 配置某些儀表類型的分佈統計資訊(例如,計時器和分佈摘要的百分位數、直方圖、SLA)。

Spring Boot 2 將一系列屬性繫結到開箱即用的儀表過濾器,讓您可以透過屬性控制指標發射。例如

management.metrics.enable.jvm=false
management.metrics.distribution.percentiles-histogram.http.server.requests=true
management.metrics.distribution.sla.http.server.requests=1ms,5ms

上述操作關閉了所有以字首 "jvm" 開頭的指標,發布了由 Spring Boot 自動配置的 http 伺服器請求指標的百分位數直方圖,並傳送小於或等於 1 毫秒和 5 毫秒 SLA 邊界的請求計數,以便您可以準確地了解有多少請求符合您的期望。SLA 分佈配置也是核心功能,可讓您視覺化更複雜的量測,例如 Apdex 分數

您可以完全翻轉根目錄下指標的啟用狀態,以產生僅適用於您想要的一小部分指標的白名單。假設您想要 JVM 指標,而不需要其他任何指標

management.metrics.enable.all=false
management.metrics.enable.jvm=true

為何 Spring Boot 2 中 /actuator/metrics 端點有所變更

在 Spring Boot 1 中提供列出所有指標的單個 REST 端點非常簡單,因為我們只有計數器和量表,而且兩者都是階層式的。更複雜的類型(如計時器)表示多個時間序列(它們至少包含計數、最大值和總和)。此外,我們的指標已變成維度的。很快就清楚地知道,無法在單個有效負載中輸出所有這些資訊。即使對於維度計數器,我們是否顯示每個標籤排列的聚合?為了簡潔起見,展平為階層式名稱,這會變成類似這樣的情況

http.server.requests.method.GET.response.200.uri./foo=100
http.server.requests.method.GET.response.500.uri./foo=1
http.server.requests.method.GET.response.200.uri./bar=5
http.server.requests.method.GET.response.400.uri./foo=1

# and now the aggregates...
http.server.requests.method.GET=107
http.server.requests.method.GET.response.200=105
http.server.requests.method.GET.uri./foo=101
http.server.requests.response.200.uri./foo=100
http.server.requests.response.500.uri./foo=1
http.server.requests.response.200.uri./bar=5
...

如您所見,這很快變得難以維持。例如,如果您想要在 MeterRegistry 的內容上建構自訂 UI,並且您知道您的 UI 只對按 URI 劃分的 http 吞吐量感興趣,而與方法、狀態等無關,那麼可以大幅縮減輸出。對於這些情況,我們建議建立一個組件,該組件僅向您的 UI 提供其所需的資料。將 MeterRegistry 注入到您的組件中,並使用其 findget 方法搜尋您需要公開的指標。然後以針對您的用途量身定制的格式序列化它們。

參與其中

Micrometer 支援可在 slack (slack.micrometer.io)、Twitter (@micrometerio) 和 Github 上取得。如有任何問題、建議或問題,請隨時與我們聯絡!

取得 Spring 電子報

隨時掌握 Spring 電子報的最新資訊

訂閱

搶先一步

VMware 提供訓練和認證,以加速您的進展。

了解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中提供對 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔。

了解更多

即將舉辦的活動

查看 Spring 社群中所有即將舉辦的活動。

查看全部