SpringBoot Actuator監(jiān)控的項目實踐
微服務(wù)的特點決定了功能模塊的部署是分布式的,大部分功能模塊都是運行在不同的機器上,彼此通過服務(wù)調(diào)用進(jìn)行交互,前后臺的業(yè)務(wù)流會經(jīng)過很多個微服務(wù)的處理和傳遞,出現(xiàn)了異常如何快速定位是哪個環(huán)節(jié)出現(xiàn)了問題?
在這種框架下,微服務(wù)的監(jiān)控顯得尤為重要。本文主要結(jié)合 Spring Boot Actuator,跟大家一起分享微服務(wù)Spring Boot Actuator 的常見用法,方便我們在日常中對我們的微服務(wù)進(jìn)行監(jiān)控治理。
1、Actuator 監(jiān)控
Spring Boot 使用“習(xí)慣優(yōu)于配置的理念”,采用包掃描和自動化配置的機制來加載依賴 Jar 中的 Spring bean,不需要任何 Xml 配置,就可以實現(xiàn) Spring 的所有配置。雖然這樣做能讓我們的代碼變得非常簡潔,但是整個應(yīng)用的實例創(chuàng)建和依賴關(guān)系等信息都被離散到了各個配置類的注解上,這使得我們分析整個應(yīng)用中資源和實例的各種關(guān)系變得非常的困難。
Actuator 是 Spring Boot 提供的對應(yīng)用系統(tǒng)的自省和監(jiān)控的集成功能,可以查看應(yīng)用配置的詳細(xì)信息,例如自動化配置信息、創(chuàng)建的 Spring beans 以及一些環(huán)境屬性等。
為了保證 actuator 暴露的監(jiān)控接口的安全性,需要添加安全控制的依賴spring-boot-start-security
依賴,訪問應(yīng)用監(jiān)控端點時,都需要輸入驗證信息。Security 依賴,可以選擇不加,不進(jìn)行安全管理,但不建議這么做。
2、Actuator 的 REST 接口
Actuator 監(jiān)控分成兩類:原生端點和用戶自定義端點;自定義端點主要是指擴展性,用戶可以根據(jù)自己的實際應(yīng)用,定義一些比較關(guān)心的指標(biāo),在運行期進(jìn)行監(jiān)控。
原生端點是在應(yīng)用程序里提供眾多 Web 接口,通過它們了解應(yīng)用程序運行時的內(nèi)部狀況。原生端點又可以分成三類:
應(yīng)用配置類:可以查看應(yīng)用在運行期的靜態(tài)信息:例如自動配置信息、加載的 springbean 信息、yml 文件配置信息、環(huán)境信息、請求映射信息;
度量指標(biāo)類:主要是運行期的動態(tài)信息,例如堆棧、請求連、一些健康指標(biāo)、metrics 信息等;
操作控制類:主要是指 shutdown,用戶可以發(fā)送一個請求將應(yīng)用的監(jiān)控功能關(guān)閉。
Actuator 提供了 13 個接口,具體如下表所示。
HTTP 方法 | 路徑 | 描述 |
---|---|---|
GET | /auditevents | 顯示應(yīng)用暴露的審計事件 (比如認(rèn)證進(jìn)入、訂單失敗) |
GET | /beans | 描述應(yīng)用程序上下文里全部的 Bean,以及它們的關(guān)系 |
GET | /conditions | 就是 1.0 的 /autoconfig ,提供一份自動配置生效的條件情況,記錄哪些自動配置條件通過了,哪些沒通過 |
GET | /configprops | 描述配置屬性(包含默認(rèn)值)如何注入Bean |
GET | /env | 獲取全部環(huán)境屬性 |
GET | /env/{name} | 根據(jù)名稱獲取特定的環(huán)境屬性值 |
GET | /flyway | 提供一份 Flyway 數(shù)據(jù)庫遷移信息 |
GET | /liquidbase | 顯示Liquibase 數(shù)據(jù)庫遷移的纖細(xì)信息 |
GET | /health | 報告應(yīng)用程序的健康指標(biāo),這些值由 HealthIndicator 的實現(xiàn)類提供 |
GET | /heapdump | dump 一份應(yīng)用的 JVM 堆信息 |
GET | /httptrace | 顯示HTTP足跡,最近100個HTTP request/repsponse |
GET | /info | 獲取應(yīng)用程序的定制信息,這些信息由info打頭的屬性提供 |
GET | /logfile | 返回log file中的內(nèi)容(如果 logging.file 或者 logging.path 被設(shè)置) |
GET | /loggers | 顯示和修改配置的loggers |
GET | /metrics | 報告各種應(yīng)用程序度量信息,比如內(nèi)存用量和HTTP請求計數(shù) |
GET | /metrics/{name} | 報告指定名稱的應(yīng)用程序度量值 |
GET | /scheduledtasks | 展示應(yīng)用中的定時任務(wù)信息 |
GET | /sessions | 如果我們使用了 Spring Session 展示應(yīng)用中的 HTTP sessions 信息 |
POST | /shutdown | 關(guān)閉應(yīng)用程序,要求endpoints.shutdown.enabled設(shè)置為true |
GET | /mappings | 描述全部的 URI路徑,以及它們和控制器(包含Actuator端點)的映射關(guān)系 |
GET | /threaddump | 獲取線程活動的快照 |
3、快速上手
3.1 pom依賴
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.6.RELEASE</version> <relativePath/> </parent> <groupId>com.example</groupId> <artifactId>spring-boot-actuator</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-boot-actuator</name> <description>spring-boot-actuator</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> </configuration> </plugin> </plugins> </build> </project>
3.2 配置文件
info.app.name=spring-boot-actuator info.app.version=1.0.0 info.app.test=test management.endpoints.web.exposure.include=* management.endpoint.health.show-details=always # management.endpoints.web.base-path=/manage management.endpoint.shutdown.enabled=true
management.endpoints.web.base-path=/manage
代表啟用單獨的url地址來監(jiān)控 Spring Boot 應(yīng)用,為了安全一般都啟用獨立的端口來訪問后端的監(jiān)控信息。management.endpoint.shutdown.enabled=true
啟用接口關(guān)閉 Spring Boot
3.3 控制器
package com.example.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping("/hello") public String index() { return "Hello World"; } }
3.4 啟動類
package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
配置完成之后,啟動項目就可以繼續(xù)驗證各個監(jiān)控功能了。
4、命令詳解
在 Spring Boot 2.x 中為了安全期間,Actuator 只開放了兩個端點 /actuator/health
和 /actuator/info
??梢栽谂渲梦募性O(shè)置打開。
可以打開所有的監(jiān)控點
management.endpoints.web.exposure.include=*
也可以選擇打開部分
management.endpoints.web.exposure.exclude=beans,trace
Actuator 默認(rèn)所有的監(jiān)控點路徑都在/actuator/*
,當(dāng)然如果有需要這個路徑也支持定制。
management.endpoints.web.base-path=/manage
設(shè)置完重啟后,再次訪問地址就會變成/manage/*
Actuator 幾乎監(jiān)控了應(yīng)用涉及的方方面面,我們重點講述一些經(jīng)常在項目中常用的命令。
4.1 health
health 主要用來檢查應(yīng)用的運行狀態(tài),這是我們使用最高頻的一個監(jiān)控點。通常使用此接口提醒我們應(yīng)用實例的運行狀態(tài),以及應(yīng)用不”健康“的原因,比如數(shù)據(jù)庫連接、磁盤空間不夠等。
默認(rèn)情況下 health 的狀態(tài)是開放的,添加依賴后啟動項目,訪問:http://localhost:8080/actuator/health
即可看到應(yīng)用的狀態(tài)。
{ "status": "UP", "details": { "diskSpace": { "status": "UP", "details": { "total": 22175952896, "free": 2316570624, "threshold": 10485760 } } } }
默認(rèn)情況下,最終的 Spring Boot 應(yīng)用的狀態(tài)是由 HealthAggregator 匯總而成的,匯總的算法是:
1 設(shè)置狀態(tài)碼順序:
setStatusOrder(Status.DOWN, Status.OUT_OF_SERVICE, Status.UP, Status.UNKNOWN);
。2 過濾掉不能識別的狀態(tài)碼。
3 如果無任何狀態(tài)碼,整個 Spring Boot 應(yīng)用的狀態(tài)是 UNKNOWN。
4 將所有收集到的狀態(tài)碼按照 1 中的順序排序。
5 返回有序狀態(tài)碼序列中的第一個狀態(tài)碼,作為整個 Spring Boot 應(yīng)用的狀態(tài)。
health 通過合并幾個健康指數(shù)檢查應(yīng)用的健康情況。Spring Boot Actuator 有幾個預(yù)定義的健康指標(biāo)比如DataSourceHealthIndicator
, DiskSpaceHealthIndicator
, MongoHealthIndicator
,RedisHealthIndicator
等,它使用這些健康指標(biāo)作為健康檢查的一部分。
舉個例子,如果你的應(yīng)用使用 Redis,RedisHealthindicator
將被當(dāng)作檢查的一部分;如果使用 MongoDB,
那么MongoHealthIndicator
將被當(dāng)作檢查的一部分。
可以在配置文件中關(guān)閉特定的健康檢查指標(biāo),比如關(guān)閉 redis 的健康檢查:
management.health.redise.enabled=false
默認(rèn),所有的這些健康指標(biāo)被當(dāng)作健康檢查的一部分。
4.2 info
info 就是我們自己配置在配置文件中以 info 開頭的配置信息,比如我們在示例項目中的配置是:
info.app.name=spring-boot-actuator info.app.version= 1.0.0 info.app.test= test
啟動示例項目,訪問:http://localhost:8080/actuator/info
返回部分信息如下:
{ "app": { "name": "spring-boot-actuator", "version": "1.0.0", "test": "test" } }
4.3 beans
根據(jù)示例就可以看出,展示了 bean 的別名、類型、是否單例、類的地址、依賴等信息。
啟動示例項目,訪問:http://localhost:8080/actuator/beans
返回部分信息如下:
[ { "context": "application:8080:management", "parent": "application:8080", "beans": [ { "bean": "embeddedServletContainerFactory", "aliases": [ ], "scope": "singleton", "type": "org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory", "resource": "null", "dependencies": [ ] }, { "bean": "endpointWebMvcChildContextConfiguration", "aliases": [ ], "scope": "singleton", "type": "org.springframework.boot.actuate.autoconfigure.EndpointWebMvcChildContextConfiguration$$EnhancerBySpringCGLIB$$a4a10f9d", "resource": "null", "dependencies": [ ] } } ]
4.4 conditions
Spring Boot 的自動配置功能非常便利,但有時候也意味著出問題比較難找出具體的原因。使用 conditions 可以在應(yīng)用運行時查看代碼了某個配置在什么條件下生效,或者某個自動配置為什么沒有生效。
啟動示例項目,訪問:http://localhost:8080/actuator/conditions
返回部分信息如下:
{ "positiveMatches": { "DevToolsDataSourceAutoConfiguration": { "notMatched": [ { "condition": "DevToolsDataSourceAutoConfiguration.DevToolsDataSourceCondition", "message": "DevTools DataSource Condition did not find a single DataSource bean" } ], "matched": [ ] }, "RemoteDevToolsAutoConfiguration": { "notMatched": [ { "condition": "OnPropertyCondition", "message": "@ConditionalOnProperty (spring.devtools.remote.secret) did not find property 'secret'" } ], "matched": [ { "condition": "OnClassCondition", "message": "@ConditionalOnClass found required classes 'javax.servlet.Filter', 'org.springframework.http.server.ServerHttpRequest'; @ConditionalOnMissingClass did not find unwanted class" } ] } } }
4.5 heapdump
返回一個 GZip 壓縮的 JVM 堆 dump
啟動示例項目,訪問:http://localhost:8080/actuator/heapdump
會自動生成一個 Jvm 的堆文件heapdump,我們可以使用 JDK 自帶的 Jvm 監(jiān)控工具 VisualVM 打開此文件查看內(nèi)存快照。
類似如下圖:
4.6 shutdown
開啟接口優(yōu)雅關(guān)閉 Spring Boot 應(yīng)用,要使用這個功能首先需要在配置文件中開啟:
management.endpoint.shutdown.enabled=true
配置完成之后,啟動示例項目,使用 curl 模擬 post 請求訪問 shutdown 接口。
shutdown 接口默認(rèn)只支持 post 請求。
curl -X POST "http://localhost:8080/actuator/shutdown" { "message": "Shutting down, bye..." }
此時你會發(fā)現(xiàn)應(yīng)用已經(jīng)被關(guān)閉。
4.7 mappings
描述全部的 URI 路徑,以及它們和控制器的映射關(guān)系
啟動示例項目,訪問:http://localhost:8080/actuator/mappings
返回部分信息如下:
{ "/**/favicon.ico": { "bean": "faviconHandlerMapping" }, "{[/hello]}": { "bean": "requestMappingHandlerMapping", "method": "public java.lang.String com.neo.controller.HelloController.index()" }, "{[/error]}": { "bean": "requestMappingHandlerMapping", "method": "public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)" } }
4.8 threaddump
/threaddump
接口會生成當(dāng)前線程活動的快照。這個功能非常好,方便我們在日常定位問題的時候查看線程的情況。 主要展示了線程名、線程ID、線程的狀態(tài)、是否等待鎖資源等信息。
啟動示例項目,訪問:http://localhost:8080/actuator/threaddump
返回部分信息如下:
[ { "threadName": "http-nio-8088-exec-6", "threadId": 49, "blockedTime": -1, "blockedCount": 0, "waitedTime": -1, "waitedCount": 2, "lockName": "java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@1630a501", "lockOwnerId": -1, "lockOwnerName": null, "inNative": false, "suspended": false, "threadState": "WAITING", "stackTrace": [ { "methodName": "park", "fileName": "Unsafe.java", "lineNumber": -2, "className": "sun.misc.Unsafe", "nativeMethod": true }, ... { "methodName": "run", "fileName": "TaskThread.java", "lineNumber": 61, "className": "org.apache.tomcat.util.threads.TaskThread$WrappingRunnable", "nativeMethod": false } ... ], "lockInfo": { "className": "java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject", "identityHashCode": 372286721 } } ... ]
生產(chǎn)出現(xiàn)問題的時候,可以通過應(yīng)用的線程快照來檢測應(yīng)用正在執(zhí)行的任務(wù)。
到此這篇關(guān)于SpringBoot Actuator監(jiān)控的項目實踐的文章就介紹到這了,更多相關(guān)SpringBoot Actuator監(jiān)控內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決spring AOP中自身方法調(diào)用無法應(yīng)用代理的問題
這篇文章主要介紹了解決spring AOP中自身方法調(diào)用無法應(yīng)用代理的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08Java實現(xiàn)獲取客戶端真實IP方法小結(jié)
本文給大家匯總介紹了2種使用java實現(xiàn)獲取客戶端真實IP的方法,主要用于獲取使用了代理訪問的來訪者的IP,有需要的小伙伴可以參考下。2016-03-03關(guān)于IDEA 2020使用 mybatis-log-plugin插件的問題
這篇文章主要介紹了關(guān)于IDEA 2020使用 mybatis-log-plugin插件的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11