javascript
最佳实践|Spring Boot 应用如何快速接入 Prometheus 监控
簡介:SpringBoot 微服務(wù)的開發(fā)、發(fā)布與部署只占其生命周期的一小部分,應(yīng)用和系統(tǒng)運維才是重中之重。而運維過程中,監(jiān)控工作更是占據(jù)重要位置。那么,為了對系統(tǒng)的狀態(tài)進行持續(xù)地觀測,面向Spring Boot應(yīng)用我們該如何快速實現(xiàn)Prometheus監(jiān)控接入。本文為大家詳細講解完整接入流程與接入事項!
作者:凡星
對于開發(fā)者而言,大部分傳統(tǒng) SSM 結(jié)構(gòu)的 MVC 應(yīng)用背后的糟糕體驗都是來自于搭建項目時的大量配置,稍有不慎就可能踩坑。為了解決上述問題,Spring Boot 應(yīng)運而生。正如其名,Spring Boot 的核心價值就是自動配置,只要存在相應(yīng) jar 包,Spring 可以自動配置。如果默認配置不能滿足需求,還可以替換掉自動配置類,使用自定義配置,快速構(gòu)建企業(yè)級應(yīng)用程序。
但構(gòu)建 Spring Boot 應(yīng)用只是第一步,隨著應(yīng)用上線之后,我們又該如何進行監(jiān)測?
基礎(chǔ)知識及概念
首先,在正式講解前,先向大家講解本次分享所需要的基本知識和概念。一般來說,搭建一套完整易用的監(jiān)測系統(tǒng)主要包含以下幾個關(guān)鍵部分。
收集監(jiān)測數(shù)據(jù)
目前,行業(yè)常見的收集監(jiān)測數(shù)據(jù)方式主要分為推送(Push)和抓取(Pull)兩個模式。以越來越廣泛應(yīng)用的 Prometheus 監(jiān)測體系舉例,Prometheus 就是以抓取(Pull)模式運行的典型系統(tǒng)。應(yīng)用及基礎(chǔ)設(shè)施的監(jiān)測數(shù)據(jù)以 OpenMetrics 標(biāo)準(zhǔn)接口的形式暴露給 Prometheus,由 Prometheus 進行定期抓取并長期存儲。
這里簡單介紹一下 OpenMetrics。作為云原生、高度可擴展的指標(biāo)協(xié)議, OpenMetrics 定義了大規(guī)模上報云原生指標(biāo)的事實標(biāo)準(zhǔn),并支持文本表示協(xié)議和 Protocol Buffers 協(xié)議,文本表示協(xié)議在其中更為常見,也是在 Prometheus 進行數(shù)據(jù)抓取時默認采用的協(xié)議。下圖是一個基于 OpenMetrics 格式的指標(biāo)表示格式樣例。
指標(biāo)的數(shù)據(jù)模型由指標(biāo)(Metric)名,以及一組 key/value 標(biāo)簽(Label)定義的,具有相同的度量名稱以及標(biāo)簽屬于相同時序集合。例如 ?acme_http_router_request_seconds_sum{path="/api/v1",method="GET"} 可以表示指標(biāo)名為 acme_http_router_request_seconds_sum,標(biāo)簽 method 值為 POST 的一次采樣點數(shù)據(jù)。采樣點內(nèi)包含一個 float64 值和一個毫秒級的 UNIX 時間戳。隨著時間推移,這些收集起來的采樣點數(shù)據(jù)將在圖表上實時繪制動態(tài)變化的線條。
目前,對于云原生體系下的絕大多數(shù)基礎(chǔ)組件,大多能夠支持以上面提到的 OpenMetrics 的文本協(xié)議格式暴露指標(biāo),對于尚未能夠支持自身暴露指標(biāo)的組件, Prometheus 社區(qū)也存在極其豐富的 Prometheus Exporter 供開發(fā)及運維人員使用。這些組件(或 Exporter)通過響應(yīng)來自 Prometheus 的定期抓取請求來及時地將自身的運行狀況記錄到 Prometheus 以便后續(xù)的處理及分析。對于應(yīng)用開發(fā)者,還可以通過 Prometheus 多語言 SDK,進行代碼埋點,將自身的業(yè)務(wù)指標(biāo)也接入到上述的 Prometheus 生態(tài)當(dāng)中。
數(shù)據(jù)可視化及分析
在獲取應(yīng)用或基礎(chǔ)設(shè)施運行狀態(tài)、資源使用情況,以及服務(wù)運行狀態(tài)等直觀信息后,通過查詢和分析多類型、多維度信息能夠方便的對節(jié)點進行跟蹤和比較。同時,通過標(biāo)準(zhǔn)易用的可視化大盤去獲知當(dāng)前系統(tǒng)的運行狀態(tài)。比較常見的解決方案就是 Grafana,作為開源社區(qū)中目前熱度很高的數(shù)據(jù)可視化解決方案,Grafana 提供了豐富的圖表形式與模板。在阿里云 ARMS Prometheus 監(jiān)控服務(wù)中,也基于 Grafana 向用戶提供了全托管版的監(jiān)測數(shù)據(jù)查詢、分析及可視化。
及時的告警和應(yīng)急管理
當(dāng)業(yè)務(wù)即將出現(xiàn)故障時,監(jiān)測系統(tǒng)需要迅速反應(yīng)并通知管理員,從而能夠?qū)栴}進行快速的處理或者提前預(yù)防問題的發(fā)生,避免出現(xiàn)對業(yè)務(wù)的影響。當(dāng)問題發(fā)生后,管理員需要對問題進行認領(lǐng)和處理。通過對不同監(jiān)測指標(biāo)以及歷史數(shù)據(jù)的分析,能夠找到并解決根源問題。
接入流程概覽
接下來,我們講講面向部署在 Kubernetes 集群上的 Spring Boot 微服務(wù)應(yīng)用如何進行 Prometheus 接入。針對 Spring Boot 應(yīng)用,社區(qū)提供了開箱即用的 Spring Boot Actuator 框架,方便 Java 開發(fā)者進行代碼埋點和監(jiān)測數(shù)據(jù)收集、輸出。從 Spring Boot 2.0 開始,Actuator 將底層改為 Micrometer,提供了更強、更靈活的監(jiān)測能力。Micrometer 是一個監(jiān)測門面,可以類比成監(jiān)測界的 Slf4j 。借助 Micrometer,應(yīng)用能夠?qū)痈鞣N監(jiān)測系統(tǒng),例如:AppOptics,Datadog,Elastic,InfluxDB 等,當(dāng)然,也包括我們今天所介紹的 Prometheus。
Micrometer 在將 Prometheus 指標(biāo)對接到 Java 應(yīng)用的指標(biāo)時,支持應(yīng)用開發(fā)者用三個類型的語義來映射:
- MicroMeter 中的 Counter 對應(yīng)于 Prometheus 中的 Counter,用來描述一個單調(diào)遞增的變量,如某個接口的訪問次數(shù),緩存命中/訪問總次數(shù)等。Timer 在邏輯上蘊含了 Counter,即如果使用 Timer 采集每個接口的響應(yīng)時間,必然也會采集訪問次數(shù)。故無需為某個接口同時指定 Timer 與 Counter 兩個指標(biāo)
- MicroMeter 中的 Gauge 對應(yīng)于 Prometheus 中的 Gauge,用來描述在一個范圍內(nèi)持續(xù)波動的變量,如 CPU 使用率,線程池任務(wù)隊列數(shù)等。
- MicroMeter 中的 Timer 對應(yīng)于 Prometheus 中的 Histogram,用來描述與時間相關(guān)的數(shù)據(jù),如某個接口 RT 時間分布等等。
- Micrometer 中的 DistributionSummary 對應(yīng) Prometheus 中的 Summary ,與 ?Histogram 類似,Summary 也是用于統(tǒng)計數(shù)據(jù)分布的,但由于數(shù)據(jù)的分布情況是在客戶端計算完成后再傳入 Prometheus 進行存儲,因此 Summary 的結(jié)果無法在多個機器之間進行數(shù)據(jù)聚合,無法統(tǒng)計全局視圖的數(shù)據(jù)分布,使用起來有一定局限性。
當(dāng)我們需要把部署在 Kubernetes 集群中的 Spring Boot 應(yīng)用接入到 Prometheus 時,需要按照代碼埋點->部署應(yīng)用->服務(wù)發(fā)現(xiàn)這個流程來進行。
首先,我們需要在代碼中引入 Spring Boot Actuator 相關(guān) maven 依賴,并對我們需要監(jiān)測的數(shù)據(jù)進行注冊,或?qū)?Controller 內(nèi)的方法打上響應(yīng)的注解。
其次,我們將埋點后的應(yīng)用部署在 Kubernetes 中,并向 Prometheus 注冊向應(yīng)用拉取監(jiān)測數(shù)據(jù)的端點(也就是 Prometheus 服務(wù)發(fā)現(xiàn))。阿里云 Prometheus 服務(wù)提供了使用 ServiceMonitor CRD 進行服務(wù)發(fā)現(xiàn)的方法。
最后在目標(biāo)應(yīng)用的監(jiān)測采集端點被 Prometheus 成功發(fā)現(xiàn)后,我們就可以開始在 Grafana 上面配置數(shù)據(jù)源及相應(yīng)的大盤了。當(dāng)然,我們同時也需要根據(jù)某些關(guān)鍵指標(biāo)進行對應(yīng)的告警配置。這些需求在阿里云 Prometheus 監(jiān)控服務(wù)都能很方便地滿足。
接入流程詳解
接下來,我們進入實戰(zhàn)演練環(huán)節(jié),這里選取一個基于 Spring Boot & Spring Cloud Alibaba 構(gòu)建的云原生微服務(wù)應(yīng)用(https://github.com/aliyun/alibabacloud-microservice-demo)作為我們改造的基線。
我們最終目標(biāo)是:
1、監(jiān)測系統(tǒng)的入口:Frontend 服務(wù)是一個基于 SpringMVC 開發(fā)的入口應(yīng)用,承接外部的客戶流量,我們主要關(guān)注的是外部接口的關(guān)鍵 RED 指標(biāo)(調(diào)用率 Rate,失敗數(shù) Error,請求耗時 Duration);
2、監(jiān)測系統(tǒng)的關(guān)鍵鏈路:對后端服務(wù) critical path 上的對象進行監(jiān)測,如線程池的隊列情況、進程內(nèi) Guava Cache 緩存的命中情況;
3、對業(yè)務(wù)強相關(guān)的自定義指標(biāo)(比如某個接口的 UV 等等);
4、對 JVM GC 及內(nèi)存使用情況進行監(jiān)測;
5、對上述指標(biāo)進行統(tǒng)一匯聚展示、以及配置關(guān)鍵指標(biāo)的告警。
第一步,引入 Spring Boot Actuator 依賴,進行初始配置
首先,我們需要引入 Spring Boot Actuator 的相關(guān)依賴,在 application.properties 配置中暴露監(jiān)測數(shù)據(jù)端口(這里定義為 8091)。成功后,我們即可訪問應(yīng)用的 8091 端口的/actuator/prometheus 路徑拿到 OpenMetrics 標(biāo)準(zhǔn)的監(jiān)測數(shù)據(jù)。
<!-- 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> # application.properties添加以下配置用于暴露指標(biāo) spring.application.name=frontendmanagement.server.port=8091 management.endpoints.web.exposure.include=* management.metrics.tags.application=${spring.application.name}第二步,代碼埋點及改造
為了獲取某個 Api 接口的 RED 指標(biāo),我們需要在對應(yīng)的接口方法上打下面的 @Timed 注解。我們以演示項目中的 index 頁面接口為例。注意這里,@Timed 注解中的 value 即為暴露到/actuator/prometheus 中的指標(biāo)名字,histogram=true 表示我們暴露這個接口請求時長的 histogram 直方圖類型指標(biāo),便于我們后續(xù)計算 P99,P90 等請求時間分布情況。
@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"; }如果我們的應(yīng)用中使用了進程內(nèi)緩存庫,比如最為常見的 Guava Cache 庫等等。如果我們想追蹤進程內(nèi)緩存的運行狀況,我們需要按照 Micrometer 提供的修飾方法,對待監(jiān)測的關(guān)鍵對象進行封裝。
- Guava Cache 改造主要是四步驟,代碼改動比較小,很容易就可以接入:
1、注入 MeterRegistry,這里注入的具體實現(xiàn)是 PrometheusMeterRegistry,由 Spring Boot 自行注入即可
2、使用工具類 api,即圖中展示的 GuavaCacheMetrics.monitor 包裝一下本地緩存
3、開啟緩存數(shù)據(jù)記錄,即調(diào)用一下.recordStats()方法
4、增加一個名稱,用于生成對應(yīng)的指標(biāo)。
- 線程池改造主要是三步驟,也并不是很復(fù)雜:
1、注入 MeterRegistry,這里注入的具體實現(xiàn)是 PrometheusMeterRegistry;
2、使用工具類 api 包裝一下線程池;
3、增加一個名稱,用于生成對應(yīng)的指標(biāo)。
當(dāng)然,我們在開發(fā)過程中一定還有許多業(yè)務(wù)強相關(guān)的自定義指標(biāo),為了監(jiān)測這些指標(biāo),我們在向 Bean 中注入 MeterRegistry 后,需要按照我們的需求和對應(yīng)場景構(gòu)造 Counter,Gauge 或 Timer(這些類型的區(qū)別和使用場景上文有提到)來進行數(shù)據(jù)統(tǒng)計,并將其注冊到 MeterRegistry 進行指標(biāo)暴露,下面是一個簡單的例子。
@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!";} }至此,我們的應(yīng)用代碼改造工作到這里就全部完成了,下一步工作就是將應(yīng)用鏡像重新構(gòu)建并重新部署到已安裝 ARMS Prometheus 的 Kubernetes 集群中。之后,我們 ARMS Prometheus 控制臺中配置 ServiceMonitor,進行服務(wù)發(fā)現(xiàn)。
添加好 ServiceMonitor 后,我們可以在 Targets 列表中看到剛注冊的應(yīng)用 Service。
第三步,看板配置
應(yīng)用的監(jiān)測數(shù)據(jù)已成功收集并存儲到 ARMS Prometheus。接下來,也是最關(guān)鍵的一步,就是根據(jù)這些數(shù)據(jù),配置相應(yīng)的大盤及告警。這里,我們借助 Grafana 社區(qū)中開源大盤模板來構(gòu)建我們自己的業(yè)務(wù)監(jiān)測模板。主要基于以下兩個模板:
- Spring Boot 2.1 Statistics:
Spring Boot 2.1 Statistics dashboard for Grafana | Grafana Labs
- JVM (Micrometer):
JVM (Micrometer) dashboard for Grafana | Grafana Labs
借助這些模板以及 ARMS Prometheus 內(nèi)置的 Grafana 服務(wù),我們可以很方便地將日常開發(fā)和運維過程中非常關(guān)心的指標(biāo)組織在一張的 Grafana Dashboard 上。這里給大家拋磚引玉一下,放一張我們內(nèi)部基于上述模板和自身業(yè)務(wù)構(gòu)建的一個真實的大盤。這里面包含了一些總覽,比如組件運行時間,內(nèi)存使用率等等,也有一些細節(jié)指標(biāo),如堆內(nèi)堆外內(nèi)存,分代 GC 情況等等,還有像接口請求的 RED 等等,這里就不過多贅述了,大家可以充分發(fā)揮自己的想象力來創(chuàng)造獨一無二的酷炫大盤~
原文鏈接
本文為阿里云原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
總結(jié)
以上是生活随笔為你收集整理的最佳实践|Spring Boot 应用如何快速接入 Prometheus 监控的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里巴巴超大规模 Kubernetes
- 下一篇: 阿里云佘俊泉:创新探索不停,边缘云持续为