Spring Boot Actuator可以幫助你監控和管理Spring Boot應用,比如健康檢查、審計、統計和HTTP追蹤等。所有的這些特性可以通過JMX或者HTTP endpoints來獲得。
Actuator同時還可以與外部應用監控系統整合,比如 Prometheus, Graphite, DataDog, Influx, Wavefront, New Relic等。這些系統提供了非常好的儀表盤、圖標、分析和告警等功能,使得你可以通過統一的接口輕松的監控和管理你的應用。
Actuator使用Micrometer來整合上面提到的外部應用監控系統。這使得只要通過非常小的配置就可以集成任何應用監控系統。
我將把Spring Boot Actuator教程分為兩部分:
- 第一部分(本文)教你如何配置Actuator和通過Http endpoints來進入這些特征。
- 第二部分教你如何整合Actuator和外部應用監控系統。
創建一個有Actuator的Spring Boot工程
首先讓我們建一個依賴acutator的簡單應用。
你可以使用Spring Boot CLI創建應用:
spring init -d=web,actuator -n=actuator actuator
或者,你可以使用Spring Initializr網站來創建應用:
增加Spring Boot Actuator到一個存在的應用
你可以增加spring-boot-actuator
模塊到一個已經存在的應用,通過使用下面的依賴。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
對于Gradle,依賴如下:
dependencies {
compile("org.springframework.boot:spring-boot-starter-actuator")
}
使用Actuator Endpoints來監控應用
Actuator創建了所謂的endpoint來暴露HTTP或者JMX來監控和管理應用。
舉個例子,有一個叫/health
的endpoint,提供了關于應用健康的基礎信息。/metrics
endpoints展示了幾個有用的度量信息,比如JVM內存使用情況、系統CPU使用情況、打開的文件等等。/loggers
endpoint展示了應用的日志和可以讓你在運行時改變日志等級。
值得注意的是,每一給actuator endpoint可以被顯式的打開和關閉。此外,這些endpoints也需要通過HTTP或者JMX暴露出來,使得它們能被遠程進入。
讓我們運行應用并且嘗試進入默認通過HTTP暴露的打開狀態的actuator endpoints。之后,我們將學習如何打開更多的endpoints并且通過HTTP暴露它們。
在應用的根目錄下打開命令行工具運行以下命令:
mvn spring-boot:run
應用默認使用8080
端口運行。一旦這個應用啟動了,你可以通過http://localhost:8080/actuator來展示所有通過HTTP暴露的endpoints。
{"_links":{"self":{"href":"http://localhost:8080/actuator","templated":false},"health":{"href":"http://localhost:8080/actuator/health","templated":false},"info":{"href":"http://localhost:8080/actuator/info","templated":false}}}
打開http://localhost:8080/actuator/health,則會顯示如下內容:
{"status":"UP"}
狀態將是UP
只要應用是健康的。如果應用不健康將會顯示DOWN
,比如與儀表盤的連接異常或者缺水磁盤空間等。下一節我們將學習spring boot如何決定應用的健康和如何修復這些健康問題。
info
endpoint(http://localhost:8080/actuator/info)展示了關于應用的一般信息,這些信息從編譯文件比如META-INF/build-info.properties
或者Git文件比如git.properties
或者任何環境的property中獲取。你將在下一節中學習如何改變這個endpoint的輸出。
默認,只有health
和info
通過HTTP暴露了出來。這也是為什么/actuator
頁面只展示了health
和info
endpoints。我們將學習如何暴露其他的endpoint。首先,讓我們看看其他的endpoints是什么。
以下是一些非常有用的actuator endpoints列表。你可以在official documentation上面看到完整的列表。
Endpoint ID | Description |
---|---|
auditevents | 顯示應用暴露的審計事件 (比如認證進入、訂單失敗) |
info | 顯示應用的基本信息 |
health | 顯示應用的健康狀態 |
metrics | 顯示應用多樣的度量信息 |
loggers | 顯示和修改配置的loggers |
logfile | 返回log file中的內容(如果logging.file或者logging.path被設置) |
httptrace | 顯示HTTP足跡,最近100個HTTP request/repsponse |
env | 顯示當前的環境特性 |
flyway | 顯示數據庫遷移路徑的詳細信息 |
liquidbase | 顯示Liquibase 數據庫遷移的纖細信息 |
shutdown | 讓你逐步關閉應用 |
mappings | 顯示所有的@RequestMapping路徑 |
scheduledtasks | 顯示應用中的調度任務 |
threaddump | 執行一個線程dump |
heapdump | 返回一個GZip壓縮的JVM堆dump |
打開和關閉Actuator Endpoints
默認,上述所有的endpints都是打開的,除了shutdown
endpoint。
你可以通過設置management.endpoint.<id>.enabled to true or false
(id
是endpoint的id)來決定打開還是關閉一個actuator endpoint。
舉個例子,要想打開shutdown
endpoint,增加以下內容在你的application.properties
文件中:
management.endpoint.shutdown.enabled=true
暴露Actuator Endpoints
默認,素偶偶的actuator endpoint通過JMX被暴露,而通過HTTP暴露的只有health
和info
。
以下是你可以通過應用的properties可以通過HTTP和JMX暴露的actuator endpoint。
-
通過HTTP暴露Actuator endpoints。
# Use "*" to expose all endpoints, or a comma-separated list to expose selected ones management.endpoints.web.exposure.include=health,info management.endpoints.web.exposure.exclude=
-
通過JMX暴露Actuator endpoints。
# Use "*" to expose all endpoints, or a comma-separated list to expose selected ones management.endpoints.jmx.exposure.include=* management.endpoints.jmx.exposure.exclude=
通過設置management.endpoints.web.exposure.include
為*
,我們可以在http://localhost:8080/actuator頁面看到如下內容。
{"_links":{"self":{"href":"http://localhost:8080/actuator","templated":false},"auditevents":{"href":"http://localhost:8080/actuator/auditevents","templated":false},"beans":{"href":"http://localhost:8080/actuator/beans","templated":false},"health":{"href":"http://localhost:8080/actuator/health","templated":false},"conditions":{"href":"http://localhost:8080/actuator/conditions","templated":false},"configprops":{"href":"http://localhost:8080/actuator/configprops","templated":false},"env":{"href":"http://localhost:8080/actuator/env","templated":false},"env-toMatch":{"href":"http://localhost:8080/actuator/env/{toMatch}","templated":true},"info":{"href":"http://localhost:8080/actuator/info","templated":false},"loggers":{"href":"http://localhost:8080/actuator/loggers","templated":false},"loggers-name":{"href":"http://localhost:8080/actuator/loggers/{name}","templated":true},"heapdump":{"href":"http://localhost:8080/actuator/heapdump","templated":false},"threaddump":{"href":"http://localhost:8080/actuator/threaddump","templated":false},"prometheus":{"href":"http://localhost:8080/actuator/prometheus","templated":false},"metrics-requiredMetricName":{"href":"http://localhost:8080/actuator/metrics/{requiredMetricName}","templated":true},"metrics":{"href":"http://localhost:8080/actuator/metrics","templated":false},"scheduledtasks":{"href":"http://localhost:8080/actuator/scheduledtasks","templated":false},"httptrace":{"href":"http://localhost:8080/actuator/httptrace","templated":false},"mappings":{"href":"http://localhost:8080/actuator/mappings","templated":false}}}
解析常用的actuator endpoint
/health endpoint
health
endpoint通過合并幾個健康指數檢查應用的健康情況。
Spring Boot Actuator有幾個預定義的健康指標比如DataSourceHealthIndicator
, DiskSpaceHealthIndicator
, MongoHealthIndicator
, RedisHealthIndicator
, CassandraHealthIndicator
等。它使用這些健康指標作為健康檢查的一部分。
舉個例子,如果你的應用使用Redis
,RedisHealthindicator
將被當作檢查的一部分。如果使用MongoDB
,那么MongoHealthIndicator
將被當作檢查的一部分。
你也可以關閉特定的健康檢查指標,比如在prpperties中使用如下命令:
management.health.mongo.enabled=false
默認,所有的這些健康指標被當作健康檢查的一部分。
顯示詳細的健康信息
health
endpoint只展示了簡單的UP
和DOWN
狀態。為了獲得健康檢查中所有指標的詳細信息,你可以通過在application.yaml
中增加如下內容:
management:
endpoint:
health:
show-details: always
一旦你打開上述開關,你在/health
中可以看到如下詳細內容:
{"status":"UP","details":{"diskSpace":{"status":"UP","details":{"total":250790436864,"free":27172782080,"threshold":10485760}}}}
health
endpoint現在包含了DiskSpaceHealthIndicator
。
如果你的應用包含database(比如MySQL),health
endpoint將顯示如下內容:
{
"status":"UP",
"details":{
"db":{
"status":"UP",
"details":{
"database":"MySQL",
"hello":1
}
},
"diskSpace":{
"status":"UP",
"details":{
"total":250790436864,
"free":100330897408,
"threshold":10485760
}
}
}
}
如果你的MySQL server沒有啟起來,狀態將會變成DOWN
:
{
"status":"DOWN",
"details":{
"db":{
"status":"DOWN",
"details":{
"error":"org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30006ms."
}
},
"diskSpace":{
"status":"UP",
"details":{
"total":250790436864,
"free":100324585472,
"threshold":10485760
}
}
}
}
創建一個自定義的健康指標
你可以通過實現HealthIndicator
接口來自定義一個健康指標,或者繼承AbstractHealthIndicator
類。
package com.example.actuator.health;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.stereotype.Component;
@Component
public class CustomHealthIndicator extends AbstractHealthIndicator {
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
// Use the builder to build the health status details that should be reported.
// If you throw an exception, the status will be DOWN with the exception message.
builder.up()
.withDetail("app", "Alive and Kicking")
.withDetail("error", "Nothing! I'm good.");
}
}
一旦你增加上面的健康指標到你的應用中去后,health
endpoint將展示如下細節:
{
"status":"UP",
"details":{
"custom":{
"status":"UP",
"details":{
"app":"Alive and Kicking",
"error":"Nothing! I'm good."
}
},
"diskSpace":{
"status":"UP",
"details":{
"total":250790436864,
"free":97949245440,
"threshold":10485760
}
}
}
}
/metrics endpoint
metrics
endpoint展示了你可以追蹤的所有的度量。
{
"names": [
"jvm.memory.max",
"http.server.requests",
"process.files.max",
...
"tomcat.threads.busy",
"process.start.time",
"tomcat.servlet.error"
]
}
想要獲得每個度量的詳細信息,你需要傳遞度量的名稱到URL中,像
http://localhost:8080/actuator/metrics/{MetricName}
舉個例子,獲得systems.cpu.usage
的詳細信息,使用以下URLhttp://localhost:8080/actuator/metrics/system.cpu.usage。它將顯示如下內容:
{
"name": "system.cpu.usage",
"measurements": [
{
"statistic": "VALUE",
"value": 0
}
],
"availableTags": []
}
/loggers endpoint
loggers
endpoint,可以通過訪問http://localhost:8080/actuator/loggers來進入。它展示了應用中可配置的loggers的列表和相關的日志等級。
你同樣能夠使用http://localhost:8080/actuator/loggers/{name}來展示特定logger的細節。
舉個例子,為了獲得root
logger的細節,你可以使用http://localhost:8080/actuator/loggers/root:
{
"configuredLevel":"INFO",
"effectiveLevel":"INFO"
}
在運行時改變日志等級
loggers
endpoint也允許你在運行時改變應用的日志等級。
舉個例子,為了改變root
logger的等級為DEBUG
,發送一個POST
請求到http://localhost:8080/actuator/loggers/root,加入如下參數
{
"configuredLevel": "DEBUG"
}
這個功能對于線上問題的排查非常有用。
同時,你可以通過傳遞null
值給configuredLevel
來重置日志等級。
/info endpoint
info
endpoint展示了應用的基本信息。它通過META-INF/build-info.properties
來獲得編譯信息,通過git.properties
來獲得Git信息。它同時可以展示任何其他信息,只要這個環境property中含有info
key。
你可以增加properties到application.yaml
中,比如:
# INFO ENDPOINT CONFIGURATION
info:
app:
name: @project.name@
description: @project.description@
version: @project.version@
encoding: @project.build.sourceEncoding@
java:
version: @java.version@
注意,我使用了Spring Boot的Automatic property expansion 特征來擴展來自maven工程的properties。
一旦你增加上面的properties,info
endpoint將展示如下信息:
{
"app": {
"name": "actuator",
"description": "Demo project for Spring Boot",
"version": "0.0.1-SNAPSHOT",
"encoding": "UTF-8",
"java": {
"version": "1.8.0_161"
}
}
}
使用Spring Security來保證Actuator Endpoints安全
Actuator endpoints是敏感的,必須保障進入是被授權的。如果Spring Security是包含在你的應用中,那么endpoint是通過HTTP認證被保護起來的。
如果沒有, 你可以增加以下以來到你的應用中去:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
接下去讓我們看一下如何覆寫spring security配置,并且定義你自己的進入規則。
下面的例子展示了一個簡單的spring securiy配置。它使用叫做EndPointRequest
的ReqeustMatcher
工廠模式來配置Actuator endpoints進入規則。
package com.example.actuator.config;
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.boot.actuate.context.ShutdownEndpoint;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {
/*
This spring security configuration does the following
1. Restrict access to the Shutdown endpoint to the ACTUATOR_ADMIN role.
2. Allow access to all other actuator endpoints.
3. Allow access to static resources.
4. Allow access to the home page (/).
5. All other requests need to be authenticated.
5. Enable http basic authentication to make the configuration complete.
You are free to use any other form of authentication.
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.requestMatchers(EndpointRequest.to(ShutdownEndpoint.class))
.hasRole("ACTUATOR_ADMIN")
.requestMatchers(EndpointRequest.toAnyEndpoint())
.permitAll()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations())
.permitAll()
.antMatchers("/")
.permitAll()
.antMatchers("/**")
.authenticated()
.and()
.httpBasic();
}
}
為了能夠測試以上的配置,你可以在application.yaml
中增加spring security用戶。
# Spring Security Default user name and password
spring:
security:
user:
name: actuator
password: actuator
roles: ACTUATOR_ADMIN
你可以在Github上看到完整的代碼。
下一部分:Spring Boot Metrics監控之Prometheus&Grafana
更多學習資源
- Spring Boot Actuator: Production-ready features
- Micrometer: Spring Boot 2’s new application metrics collector