在企業級應用中,學習了如何進行SpringBoot應用的功能開發,以及如何寫單元測試、集成測試等還是不夠的。在實際的軟件開發中還需要:應用程序的監控和管理。SpringBoot的Actuator模塊實現了應用的監控與管理。
Actuator簡介
生產系統中,往往需要對系統實際運行的情況(例如cpu、io、disk、db、業務功能等指標)進行監控運維。在SpringBoot項目中Actuator模塊提供了眾多HTTP接口端點(Endpoint),來提供應用程序運行時的內部狀態信息。
Actuator模塊提供了一個監控和管理生產環境的模塊,可以使用http、jmx、ssh、telnet等來管理和監控應用。包括應用的審計(Auditing)、健康(health)狀態信息、數據采集(metrics gathering)統計等監控運維的功能。同時,提供了可以擴展 Actuator端點(Endpoint)自定義監控指標。這些指標都是以JSON接口數據的方式呈現。
Actuator的使用
使用Spring Boot Actuator需要加入如下依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
actuator並沒有默認集成在自動配置中,而在作為獨立的項目來呈現的。當引入了上面的依賴,默認會引入actuator相關的兩個項目:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
</dependency>
其中spring-boot-actuator為功能實現,spring-boot-actuator-autoconfigure為自動配置。
需要注意:因SpringBoot Actuator會暴露服務的詳細信息,為了保障安全性,建議添加安全控制的相關依賴spring-boot-starter-security,這樣在訪問應用監控端點時,都需要輸入驗證信息。所需依賴如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
關於security的使用我們在此不進行展開,可在application文件中配置相應的訪問密碼:
spring:
security:
user:
name: admin
password: admin
在下面的內容中為了方便,我們暫時不引入security。
經過以上步驟的操作,啟動SpringBoot項目,actuator便自動集成配置了,可通過:http://localhost:8080/actuator 訪問,結果如下:
{
"_links": {
"self": {
"href": "http://localhost:8080/actuator",
"templated": false
},
"health": {
"href": "http://localhost:8080/actuator/health",
"templated": false
},
"health-component": {
"href": "http://localhost:8080/actuator/health/{component}",
"templated": true
},
"health-component-instance": {
"href": "http://localhost:8080/actuator/health/{component}/{instance}",
"templated": true
},
"info": {
"href": "http://localhost:8080/actuator/info",
"templated": false
}
}
}
默認支持的鏈接有:
/actuator
/actuator/health
/health/{component}/{instance}
/health/{component}
/actuator/info
可以在application配置文件中配置開啟更多的監控信息:
management:
endpoints:
web:
exposure:
include: '*'
# base-path: /monitor
endpoint:
health:
show-details: always
shutdown:
enabled: true
- management.endpoints.web.exposure.include='*',代表開啟全部監控,也可僅配置需要開啟的監控,如: management.endpoints.web.exposure.include=beans,trace。
- management.endpoint.health.show-details=always,health endpoint開啟顯示全部細節。默認情況下/actuator/health是公開的,但不顯示細節。
- management.endpoints.web.base-path=/monitor,啟用指定的url地址訪問根路徑,默認路徑為/actuator/*,開啟則訪問路徑變為/monitor/*。
- management.endpoint.shutdown.enabled=true,啟用接口關閉SpringBoot。
監控信息如果需要跨越調用,可通過CORS配置來支持,默認處於禁用狀態。設置management.endpoints.web.cors.allowed-origins屬性后開啟。
比如允許來自https://www.choupangxia.com 域的GET和POST調用:
management:
endpoints:
web:
cors:
allowed-origins: https://www.choupangxia.com
allowed-methods: GET,POST
REST接口
Spring Boot Actuator提供了非常豐富的監控接口,可以通過這些接口了解應用程序運行時的內部狀況。Actuator也支持用戶自定義添加端點,可以根據實際應用,定義一些比較關心的指標,在運行期進行監控。
HTTP方法 | 路徑 | 描述 |
---|---|---|
GET | /auditevents | 顯示當前應用程序的審計事件信息 |
GET | /beans | 顯示一個應用中所有Spring Beans的完整列表 |
GET | /conditions | 顯示配置類和自動配置類(configuration and auto-configuration classes)的狀態及它們被應用或未被應用的原因。 |
GET | /configprops | 顯示一個所有@ConfigurationProperties的集合列表 |
GET | /env | 顯示來自Spring的ConfigurableEnvironment的屬性。 |
GET | /flyway | 顯示數據庫遷移路徑,如果有的話。 |
GET | /health | 顯示應用的健康信息(當使用一個未認證連接訪問時顯示一個簡單的’status’,使用認證連接訪問則顯示全部信息詳情) |
GET | /info | 顯示任意的應用信息 |
GET | /liquibase | 展示任何Liquibase數據庫遷移路徑,如果有的話 |
GET | /metrics | 展示當前應用的metrics信息 |
GET | /mappings | 顯示一個所有@RequestMapping路徑的集合列表 |
GET | /scheduledtasks | 顯示應用程序中的計划任務 |
GET | /sessions | 允許從Spring會話支持的會話存儲中檢索和刪除(retrieval and deletion)用戶會話。使用Spring Session對反應性Web應用程序的支持時不可用。 |
POST | /shutdown | 允許應用以優雅的方式關閉(默認情況下不啟用) |
GET | /threaddump | 執行一個線程dump |
如果使用web應用(Spring MVC, Spring WebFlux, 或者 Jersey),還可以使用以下接口:
HTTP方法 | 路徑 | 描述 |
---|---|---|
GET | /heapdump | 返回一個GZip壓縮的hprof堆dump文件 |
GET | /jolokia | 通過HTTP暴露JMX beans(當Jolokia在類路徑上時,WebFlux不可用) |
GET | /logfile | 返回日志文件內容(如果設置了logging.file或logging.path屬性的話),支持使用HTTP Range頭接收日志文件內容的部分信息 |
GET | /prometheus | 以可以被Prometheus服務器抓取的格式顯示metrics信息 |
接口詳解
health主要用來檢查應用的運行狀態,這是使用頻次最高的監控點。通常使用此接口顯示應用實例的運行狀態,以及應用不“健康”的原因,比如數據庫連接、磁盤空間不夠等。
默認情況下health的狀態是開放的,訪問:http://localhost:8080/actuator/health 即可看到應用的狀態。
{
"status" : "UP"
}
設置狀態碼順序:setStatusOrder(Status.DOWN,Status.OUT_OF_SERVICE, Status.UP, Status.UNKNOWN)。
過濾掉不能識別的狀態碼。如果無任何狀態碼,整個SpringBoot應用的狀態是UNKNOWN。將所有收集到的狀態碼排序。返回有序狀態碼序列中的第一個狀態碼,作為整個SpringBoot應用的狀態。
Health通過合並幾個健康指數檢查應用的健康情況。SpringBoot Actuator會自動配置以下內容:
名稱 | 描述 |
---|---|
CassandraHealthIndicator | 檢查Cassandra數據庫是否已啟動。 |
CouchbaseHealthIndicator | 檢查Couchbase群集是否已啟動。 |
DiskSpaceHealthIndicator | 檢查磁盤空間不足。 |
DataSourceHealthIndicator | 檢查是否可以建立連接DataSource。 |
ElasticsearchHealthIndicator | 檢查Elasticsearch集群是否已啟動。 |
InfluxDbHealthIndicator | 檢查InfluxDB服務器是否已啟動。 |
JmsHealthIndicator | 檢查JMS代理是否啟動。 |
MailHealthIndicator | 檢查郵件服務器是否已啟動。 |
MongoHealthIndicator | 檢查Mongo數據庫是否已啟動。 |
Neo4jHealthIndicator | 檢查Neo4j服務器是否已啟動。 |
RabbitHealthIndicator | 檢查Rabbit服務器是否已啟動。 |
RedisHealthIndicator | 檢查Redis服務器是否啟動。 |
SolrHealthIndicator | 檢查Solr服務器是否已啟動。 |
可以通過設置 management.health.defaults.enabled屬性來全部禁用。
原生端點
原生端點分為三大類:
- 應用配置類:獲取應用程序中加載的應用配置、環境變量、自動化配置報告等與Spring Boot應用密切相關的配置類信息。
- 度量指標類:獲取應用程序運行過程中用於監控的度量指標,比如:內存信息、線程池信息、HTTP請求統計等。
- 操作控制類:提供了對應用的關閉等操作類功能。
應用配置類
/conditions:該端點用來獲取應用的自動化配置報告,其中包括所有自動化配置的候選項。同時還列出了每個候選項自動化配置的各個先決條件是否滿足。該端點可以幫助我們方便的找到一些自動化配置為什么沒有生效的具體原因。
該報告內容將自動化配置內容分為兩部分:positiveMatches中返回的是條件匹配成功的自動化配置和negativeMatches中返回的是條件匹配不成功的自動化配置。
部分代碼如下:
"contexts": {
"application": {
"positiveMatches": {
"MsgAutoConfiguration": [
{
"condition": "OnClassCondition",
"message": "@ConditionalOnClass found required class 'com.secbro2.msg.MsgService'"
}
],
"MsgAutoConfiguration#msgService": [
{
"condition": "OnPropertyCondition",
"message": "@ConditionalOnProperty (msg.enabled=true) matched"
},
{
"condition": "OnBeanCondition",
"message": "@ConditionalOnMissingBean (types: com.secbro2.msg.MsgService; SearchStrategy: all) did not find any beans"
}
],
/info:就是在配置文件中配置的以info開頭的信息,如配置為:
info:
app:
name: spring-boot-actuator
version: 1.0.0
返回結果:
{
"app":{
"name":"spring-boot-actuator",
"version":"1.0.0"
}
}
info中配置的參數也可以通過符號*@*包圍的屬性值來自pom.xml文件中的元素節點。如下:
info:
build:
artifact: @project.artifactId@
name: @project.name@
description: @project.description@
ersion: @project.version@
返回結果:
{
"build": {
"artifact": "spring-learn",
"name": "spring-learn",
"description": "Demo project for Spring Boot",
"ersion": "0.0.1-SNAPSHOT"
}
}
/beans:該端點用來獲取應用上下文中創建的所有Bean。
{
"contexts": {
"application": {
"beans": {
"endpointCachingOperationInvokerAdvisor": {
"aliases": [],
"scope": "singleton",
"type": "org.springframework.boot.actuate.endpoint.invoker.cache.CachingOperationInvokerAdvisor",
"resource": "class path resource [org/springframework/boot/actuate/autoconfigure/endpoint/EndpointAutoConfiguration.class]",
"dependencies": ["environment"]
},
"defaultServletHandlerMapping": {
"aliases": [],
"scope": "singleton",
"type": "org.springframework.web.servlet.HandlerMapping",
"resource": "class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]",
"dependencies": []
},
},
"parentId": null
}
}
}
接口展現了bean的別名、類型、是否單例、類的地址、依賴等信息。
/configprops:該端點用來獲取應用中配置的屬性信息報告。
{
"spring.transaction-org.springframework.boot.autoconfigure.transaction.TransactionProperties": {
"prefix": "spring.transaction",
"properties": {}
}
}
上面展示了TransactionProperties屬性的配置信息。
/mappings:該端點用來返回所有SpringMVC的控制器映射關系報告。
{
"handler": "Actuator web endpoint 'beans'",
"predicate": "{GET /actuator/beans, produces [application/vnd.spring-boot.actuator.v2+json || application/json]}",
"details": {
"handlerMethod": {
"className": "org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping.OperationHandler",
"name": "handle",
"descriptor": "(Ljavax/servlet/http/HttpServletRequest;Ljava/util/Map;)Ljava/lang/Object;"
},
"requestMappingConditions": {
"consumes": [],
"headers": [],
"methods": ["GET"],
"params": [],
"patterns": ["/actuator/beans"],
"produces": [{
"mediaType": "application/vnd.spring-boot.actuator.v2+json",
"negated": false
}, {
"mediaType": "application/json",
"negated": false
}]
}
}
}
/env:該端點與/configprops不同,它用來獲取應用所有可用的環境屬性報告。包括:環境變量、JVM屬性、應用的配置配置、命令行中的參數。
度量指標類
應用配置類提供的指標為靜態報告,而度量指標類端點提供的報告內容則是動態變化的,提供了應用程序在運行過程中的一些快照信息,比如:內存使用情況、HTTP請求統計、外部資源指標等。這些端點對於構建微服務架構中的監控系統非常有幫助。
/metrics:該端點用來返回當前應用的各類重要度量指標,比如:內存信息、線程信息、垃圾回收信息等。
{
"names": [
"jvm.memory.max",
"jvm.threads.states",
"http.server.requests",
"process.files.max",
"jvm.gc.memory.promoted",
"system.load.average.1m",
"jvm.memory.used",
"jvm.gc.max.data.size",
"jvm.gc.pause",
"jvm.memory.committed",
"system.cpu.count",
"logback.events",
"tomcat.global.sent",
"jvm.buffer.memory.used",
"tomcat.sessions.created",
"jvm.threads.daemon",
"system.cpu.usage",
"jvm.gc.memory.allocated",
"tomcat.global.request.max",
"tomcat.global.request",
"tomcat.sessions.expired",
"jvm.threads.live",
"jvm.threads.peak",
"tomcat.global.received",
"process.uptime",
"tomcat.sessions.rejected",
"process.cpu.usage",
"tomcat.threads.config.max",
"jvm.classes.loaded",
"jvm.classes.unloaded",
"tomcat.global.error",
"tomcat.sessions.active.current",
"tomcat.sessions.alive.max",
"jvm.gc.live.data.size",
"tomcat.threads.current",
"process.files.open",
"jvm.buffer.count",
"jvm.buffer.total.capacity",
"tomcat.sessions.active.max",
"tomcat.threads.busy",
"process.start.time"
]
}
從上面的示例中有這些重要的度量值:
- 系統信息:包括處理器數量processors、運行時間uptime和instance.uptime、系統平均負載systemload.average。
- mem.*:內存概要信息,包括分配給應用的總內存數量以及當前空閑的內存數量。這些信息來自java.lang.Runtime。
- heap.*:堆內存使用情況。這些信息來自java.lang.management.MemoryMXBean接口中getHeapMemoryUsage方法獲取的java.lang.management.MemoryUsage。
- nonheap.*:非堆內存使用情況。這些信息來自java.lang.management.MemoryMXBean接口中getNonHeapMemoryUsage方法獲取的java.lang.management.MemoryUsage。
- threads.*:線程使用情況,包括線程數、守護線程數(daemon)、線程峰值(peak)等,這些數據均來自java.lang.management.ThreadMXBean。
- classes.*:應用加載和卸載的類統計。這些數據均來自java.lang.management.ClassLoadingMXBean。
- gc.*:垃圾收集器的詳細信息,包括垃圾回收次數gc.ps_scavenge.count、垃圾回收消耗時間gc.ps_scavenge.time、標記-清除算法的次數gc.ps_marksweep.count、標記-清除算法的消耗時間gc.ps_marksweep.time。這些數據均來自java.lang.management.GarbageCollectorMXBean。
- httpsessions.*:Tomcat容器的會話使用情況。包括最大會話數httpsessions.max和活躍會話數httpsessions.active。該度量指標信息僅在引入了嵌入式Tomcat作為應用容器的時候才會提供。
- gauge.*:HTTP請求的性能指標之一,它主要用來反映一個絕對數值。比如上面示例中的gauge.response.hello: 5,它表示上一次hello請求的延遲時間為5毫秒。
- counter.*:HTTP請求的性能指標之一,它主要作為計數器來使用,記錄了增加量和減少量。如上示例中counter.status.200.hello: 11,它代表了hello請求返回200狀態的次數為11。
/threaddump:會生成當前線程活動的快照。方便我們在日常定位問題的時候查看線程的情況。主要展示了線程名、線程ID、線程的狀態、是否等待鎖資源等信息。
{
"threads": [{
"threadName": "Reference Handler",
"threadId": 2,
"blockedTime": -1,
"blockedCount": 2,
"waitedTime": -1,
"waitedCount": 0,
"lockName": null,
"lockOwnerId": -1,
"lockOwnerName": null,
"daemon": true,
"inNative": false,
"suspended": false,
"threadState": "RUNNABLE",
"priority": 10,
"stackTrace": [{
"classLoaderName": null,
"moduleName": "java.base",
"moduleVersion": "11.0.4",
"methodName": "waitForReferencePendingList",
"fileName": "Reference.java",
"lineNumber": -2,
"className": "java.lang.ref.Reference",
"nativeMethod": true
}
...
"lockedMonitors": [],
"lockedSynchronizers": [{
"className": "java.util.concurrent.locks.ReentrantLock$NonfairSync",
"identityHashCode": 2060076420
}],
"lockInfo": null
...
{
"threadName": "DestroyJavaVM",
"threadId": 42,
"blockedTime": -1,
"blockedCount": 0,
"waitedTime": -1,
"waitedCount": 0,
"lockName": null,
"lockOwnerId": -1,
"lockOwnerName": null,
"daemon": false,
"inNative": false,
"suspended": false,
"threadState": "RUNNABLE",
"priority": 5,
"stackTrace": [],
"lockedMonitors": [],
"lockedSynchronizers": [],
"lockInfo": null
}]
}
/trace:該端點用來返回基本的HTTP跟蹤信息。默認情況下,跟蹤信息的存儲采用。
操作控制類
/shutdown:配置文件中配置開啟此功能:
management.endpoint.shutdown.enabled=true
使用 curl 模擬 post 請求此接口:
curl -X POST "http://localhost:8080/actuator/shutdown"
顯示結果為:
{
"message": "Shutting down, bye..."
}
小結
本篇文章介紹了SpringBoot Actuator監控的基本功能和詳解,下篇文章將會帶大家了解一下該功能在Spring Boot中的實現原理。歡迎關注公眾號“程序新視界”。
原文鏈接:《Spring Boot Actuator監控使用詳解》