全部產品
Search
文件中心

Managed Service for Prometheus:Spring Boot應用如何快速接入Prometheus監控

更新時間:Jul 06, 2024

在使用Spring Boot應用過程中,為了對系統的狀態進行持續地觀測,您可以將Spring Boot應用接入Prometheus監控。本文介紹如何將Spring Boot應用快速接入Prometheus監控。

背景資訊

對於開發人員而言,大部分傳統SSM結構的MVC應用背後的糟糕體驗都是來自於搭建專案時的大量配置,稍有不慎就可能導致配置出錯。為瞭解決這個問題,Spring Boot應運而生。Spring Boot的核心價值就是自動設定,只要存在相應Jar包,Spring Boot可以自動設定,如果預設配置不能滿足需求,您還可以替換掉自動設定類,使用自訂配置快速構建企業級應用程式。

構建Spring Boot應用以及該應用上線之後,您需要對該應用進行監測。一般來說,搭建一套完整易用的監測系統主要包含以下幾個關鍵區段。

收集監測資料

目前,行業常見的收集監測資料方式主要分為推送(Push)和抓取(Pull)兩個模式。以越來越廣泛應用的Prometheus監測體系舉例,可觀測監控 Prometheus 版就是以抓取(Pull)模式啟動並執行典型系統。應用及基礎設施的監測資料以OpenMetrics標準介面的形式暴露給可觀測監控 Prometheus 版,然後由可觀測監控 Prometheus 版進行定期抓取並長期儲存。

OpenMetrics,是雲原生、高度可擴充的指標協議。 OpenMetrics定義了大規模上報雲原生指標的事實標準,並支援文本表示協議和Protocol Buffers協議,文本表示協議在其中更為常見,也是在可觀測監控 Prometheus 版進行資料抓取時預設採用的協議。下圖是一個基於OpenMetrics格式的指標表示格式範例。

ert

說明

指標的資料模型由指標(Metric)名,以及一組Key/Value標籤(Label)定義的,具有相同的度量名稱以及標籤屬於相同時序集合。例如acme_http_router_request_seconds_sum{path="/api/v1",method="GET"} 可以表示指標名為acme_http_router_request_seconds_sum,標籤method值為GET的一次採樣點資料。採樣點內包含一個Float64值和一個毫秒級的UNIX時間戳記。隨著時間推移,這些收集起來的採樣點資料將在圖表上即時繪製動態變化的線條。

目前,對於雲原生體系下的絕大多數基礎組件能夠支援OpenMetrics的文本協議格式暴露指標,對於暫不能支援自身暴露指標的組件, Prometheus社區也存在極其豐富的Prometheus Exporter供開發及營運人員使用。這些組件(或Exporter)通過響應來自可觀測監控 Prometheus 版的定期抓取請求來及時地將自身的健全狀態記錄到可觀測監控 Prometheus 版以便後續的處理及分析。對於應用開發人員,您還可以通過可觀測監控 Prometheus 版的多語言SDK,進行代碼埋點,將自身的業務指標也接入到上述的Prometheus生態當中。

資料視覺效果及分析

在擷取應用或基礎設施運行狀態、資源使用方式,以及服務運行狀態等直觀資訊後,通過查詢和分析多類型、多維度資訊能夠方便地對節點進行跟蹤和比較。同時,通過標準易用的可視化大盤去獲知當前系統的運行狀態。比較常見的解決方案就是Grafana,作為開源社區中目前熱度很高的資料視覺效果解決方案,Grafana提供了豐富的圖表形式與模板。在可觀測監控 Prometheus 版中,也為您提供了基於Grafana全託管版的監測資料查詢、分析及可視化。

及時的警示和應急管理

當業務即將出現故障時,監測系統需要迅速反應並通知管理員,從而能夠對問題進行快速的處理或者提前預防問題的發生,避免出現對業務的影響。當問題發生後,管理員需要對問題進行認領和處理。通過對不同監測指標以及歷史資料的分析,能夠找到並解決根源問題。

接入流程概述

針對Spring Boot應用,社區提供了開箱即用的Spring Boot Actuator架構,方便Java開發人員進行代碼埋點和監測資料收集、輸出。從Spring Boot 2.0開始,Actuator將底層改為Micrometer,同時提供了更強、更靈活的監測能力。Micrometer是一個監測門面,可以類比成監測界的Slf4j ,藉助Micrometer,應用則能夠對接各種監測系統。例如,AppOptics、Datadog、Elastic、InfluxDB以及可觀測監控 Prometheus 版等。

Micrometer在將可觀測監控 Prometheus 版指標對接到Java應用的指標時,支援應用開發人員用三個類型的語義來映射:

Micrometer指標類型

可觀測監控 Prometheus 版監控的指標類型

典型用途

Counter

Counter

計數器,單調遞增情境。例如,統計PV和UV,介面調用次數等。

Gauge

Gauge

持續波動的變數。例如,資源使用率、系統負載、請求隊列長度等。

Timer

Histogram

統計資料分布。例如,統計某介面調用延時的P50、P90、P99等。

DistributionSummary

Summary

統計資料分布,與Histogram用途類似。

  • Micrometer中的Counter指標類型對應於可觀測監控 Prometheus 版中的Counter指標類型,用來描述一個單調遞增的變數。如某個介面的訪問次數、快取命中或者訪問總次數等。Timer在邏輯上蘊含了Counter,即如果使用Timer採集每個介面的回應時間,必然也會採集訪問次數。因此無需為某個介面同時指定Timer與Counter兩個指標。

  • MicroMeter中的Gauge指標類型對應於可觀測監控 Prometheus 版中的Gauge指標類型,用來描述在一個範圍內持續波動的變數。如CPU使用率、線程池任務隊列數等。

  • MicroMeter中的Timer指標類型對應於可觀測監控 Prometheus 版中的Histogram,用來描述與時間相關的資料。如某個介面RT時間分布等。

  • Micrometer中的DistributionSummary指標類型對應可觀測監控 Prometheus 版中的Summary指標類型 ,與Histogram類似,Summary也是用於統計資料分布的,但由於資料的分布情況是在用戶端計算完成後再傳入可觀測監控 Prometheus 版進行儲存,因此Summary的結果無法在多個機器之間進行資料彙總,無法統計全域視圖的資料分布,使用起來有一定局限性。

接入流程

當您需要把部署在Kubernetes叢集中的Spring Boot應用接入到可觀測監控 Prometheus 版時,需要按照代碼埋點>部署應用>服務發現這個流程來進行。

首先,您需要在代碼中引入Spring Boot Actuator相關Maven依賴,並對您需要監測的資料進行註冊,或對Controller內的方法打上相應的註解。

其次,您需要將埋點後的應用部署在Kubernetes中,並向可觀測監控 Prometheus 版註冊嚮應用拉取監測資料的端點(即可觀測監控 Prometheus 版的服務發現)。阿里雲Prometheus服務提供了使用ServiceMonitor CRD進行服務發現的方法。

最後,在目標應用的監測採集端點被可觀測監控 Prometheus 版成功發現後,您就可以在Grafana上配置資料來源及相應的大盤。同時您也可以根據某些關鍵計量進行對應的警示配置。

最終目標

通過將部署在Kubernetes叢集中的Spring Boot應用接入到可觀測監控 Prometheus 版,希望能夠實現以下幾點目標:

  • 監測系統的入口:Frontend服務是一個基於SpringMVC開發的入口應用,承接外部的客戶流量,這裡主要關注的是外部介面的關鍵RED指標。例如,調用率Rate、失敗數Error、請求耗時Duration。

  • 監測系統的關鍵鏈路:對後端服務critical path上的對象進行監測。例如,線程池的隊列情況、進程內Guava Cache緩衝的命中情況。

  • 實現對業務強相關的自訂指標進行監測。例如,某個介面的UV等。

  • 實現對JVM GC及記憶體使用量情況進行監測。

  • 實現對上述指標進行統一匯聚展示,以及配置關鍵計量的警示。

步驟一:引入Spring Boot Actuator依賴,進行初始配置

這裡選取一個基於Spring Boot和Spring Cloud Alibaba構建的雲原生微服務應用,為您介紹部署在Kubernetes叢集上的Spring Boot微服務應用如何進行Prometheus接入的具體接入流程。

  1. 執行如下程式碼片段,引入Spring Boot Actuator的相關依賴。

    <!-- spring-boot-actuator依賴 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!-- prometheus依賴 -->
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-registry-prometheus</artifactId>
    </dependency>
  2. 在application.properties中添加相關配置暴露監測資料連接埠。例如,連接埠為8091。

    # application.properties添加以下配置用於暴露指標
    spring.application.name=frontend
    
    management.server.port=8091
    management.endpoints.web.exposure.include=*
    management.metrics.tags.application=${spring.application.name}

    配置成功後,即可訪問該應用的8091連接埠,然後您可以在該連接埠的/actuator/prometheus路徑中擷取OpenMetrics標準的監測資料。

步驟二:代碼埋點及改造

若要擷取某個API介面的RED指標,您需要在對應的介面方法上打@Timed註解。這裡以index頁面介面為例打@Timed註解,如下程式碼片段所示。

@Timed(value = "main_page_request_duration", description = "Time taken to return main page", histogram = true)
@ApiOperation(value = "首頁", tags = {"首頁操作頁面"})
@GetMapping("/")
public String index(Model model) {
    model.addAttribute("products", productDAO.getProductList());

    model.addAttribute("FRONTEND_APP_NAME", Application.APP_NAME);
    model.addAttribute("FRONTEND_SERVICE_TAG", Application.SERVICE_TAG);
    model.addAttribute("FRONTEND_IP", registration.getHost());

    model.addAttribute("PRODUCT_APP_NAME", PRODUCT_APP_NAME);
    model.addAttribute("PRODUCT_SERVICE_TAG", PRODUCT_SERVICE_TAG);
    model.addAttribute("PRODUCT_IP", PRODUCT_IP);

    model.addAttribute("new_version", StringUtils.isBlank(env));
    return "index.html";
}
說明

其中value即為暴露到/actuator/prometheus中的指標名字,histogram=true表示暴露這個介面請求時間長度的histogram長條圖類型指標,便於您後續計算P90、P99等請求時間分布情況。

若您的應用中使用了進程內緩衝庫(例如,最常見的Guava Cache庫等)且需要追蹤進程內緩衝的健全狀態,您可以按照Micrometer提供的修飾方法,對於待監測的關鍵對象進行封裝。

Guava Cache改造

  1. 注入MeterRegistry,這裡注入的具體實現是PrometheusMeterRegistry,由Spring Boot自行注入即可。

  2. 使用工具類API封裝本機快取,即如下圖中的GuavaCacheMetrics.monitor。

  3. 開啟快取資料記錄,即調用.recordStats()方法。

  4. 為Cache對象命名,用於產生對應的指標。

eru

線程池改造

  1. 注入MeterRegistry,這裡注入的具體實現是PrometheusMeterRegistry。

  2. 使用工具類API封裝線程池。

  3. 為線程池命名,用於產生對應的指標。

ert

在開發過程中還會涉及許多業務強相關的自訂指標,為了監測這些指標,在往Bean中注入MeterRegistry後,您還需要按照需求和對應情境構造Counter、Gauge或Timer來進行資料統計,並將其註冊到MeterRegistry進行指標暴露,樣本如下。

@Service
public class DemoService {

    Counter visitCounter;

    public DemoService(MeterRegistry registry) {
        visitCounter = Counter.builder("visit_counter")
            .description("Number of visits to the site")
            .register(registry);
    }

    public String visit() {
        visitCounter.increment();
        return "Hello World!";
    }    
}

至此,您對應用的代碼改造工作已全部完成。然後您需要將應用鏡像重新構建並部署到已安裝可觀測監控 Prometheus 版的Kubernetes叢集中,並在可觀測監控 Prometheus 版控制台中配置ServiceMonitor,進行服務發現。更多資訊,請參見Prometheus執行個體 for Container Service管理Kubernetes叢集服務發現

ServiceMonitor配置完成後,您可以在Targets列表中查看到剛註冊的Service應用。

erti

步驟三:看板配置

應用的監測資料已成功收集並儲存到可觀測監控 Prometheus 版,因此您可以配置相應的大盤及警示來查看監控到的資料。這裡,為您提供以下兩個Grafana社區中的開源大盤模板來構建您自己的業務監測模板。

藉助以上模板以及可觀測監控 Prometheus 版內建的Grafana服務,您可以根據自己的需求,將日常開發和營運過程中需要重點關注的指標展示在同一個Grafana Dashboard頁面上,建立屬於您的個人化大盤,便於日常監測。例如,這裡基於上述模板和自身業務構建了一個真實的大盤,包含總覽、組件已耗用時間,記憶體使用量率、堆內堆外記憶體、分代GC情況等。

wsd