一、什么是 Actuator
Spring Boot Actuator 模塊提供了生產級別的功能,比如健康檢查,審計,指標收集,HTTP 跟蹤等,幫助我們監控和管理Spring Boot 應用。
這個模塊是一個采集應用內部信息暴露給外部的模塊,上述的功能都可以通過HTTP 和 JMX 訪問。
因為暴露內部信息的特性,Actuator 也可以和一些外部的應用監控系統整合(Prometheus, Graphite, DataDog, Influx, Wavefront, New Relic等)。
這些監控系統提供了出色的儀表板,圖形,分析和警報,可幫助你通過一個統一友好的界面,監視和管理你的應用程序。
Actuator使用Micrometer與這些外部應用程序監視系統集成。這樣一來,只需很少的配置即可輕松集成外部的監控系統。
Micrometer 為 Java 平台上的性能數據收集提供了一個通用的 API,應用程序只需要使用 Micrometer 的通用 API 來收集性能指標即可。
Micrometer 會負責完成與不同監控系統的適配工作。這就使得切換監控系統變得很容易。
需要注意的是:
SpringBoot 1.x 和 2.x 的 Actuator 監控設定差超多,不僅提供的 endpoint 路徑不一樣,連 application.properties 的配置也不一樣,此處介紹的為 SpringBoot 2.x 版本。
二、集成 Actuator
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
只要加上了這個 maven dependency,SpringBoot 在運行時就會自動開啟/actuator/health和/actuator/info這兩個 endpoint,我們就可以透過這兩個 endpoint 查看當前 SpringBoot 運行的情況。
Actuator 其實還提供更多樣化的 endpoint 讓我們監控 SpringBoot Application,但是因為安全因素,所以需要另外設置才能打開這些 endpoint,詳細的設置方式下面解說。
訪問http://localhost:8099/actuator,查看暴露出來的端點:

三、Endpoints 介紹
Spring Boot 提供了所謂的 endpoints (下文翻譯為端點)給外部來與應用程序進行訪問和交互。
打比方來說,/health 端點 提供了關於應用健康情況的一些基礎信息。metrics 端點提供了一些有用的應用程序指標(JVM 內存使用、系統CPU使用等)。
這些 Actuator 模塊本來就有的端點我們稱之為原生端點。根據端點的作用的話,我們大概可以分為三大類:
- 應用配置類:獲取應用程序中加載的應用配置、環境變量、自動化配置報告等與Spring Boot應用密切相關的配置類信息。
- 度量指標類:獲取應用程序運行過程中用於監控的度量指標,比如:內存信息、線程池信息、HTTP請求統計等。
- 操作控制類:提供了對應用的關閉等操作類功能。
需要注意的就是:
- 每一個端點都可以通過配置來單獨禁用或者啟動
- 不同於Actuator 1.x,Actuator 2.x 的大多數端點默認被禁掉。 Actuator 2.x 中的默認端點增加了
/actuator前綴。默認暴露的兩個端點為/actuator/health和/actuator/info
Actuator 提供的所有 endpoint:
此處使用的是 SpringBoot 2.2.8 版本,Spring 官方文件
| HTTP方法 | Endpoint | 描述 |
|---|---|---|
| GET | /actuator | 查看有哪些 Actuator endpoint 是開放的 |
| GET | /actuator/auditevent | 查看 audit 的事件,例如認證進入、訂單失敗,需要搭配 Spring security 使用,sample code |
| GET | /actuator/beans | 查看運行當下裡面全部的 bean,以及他們的關係 |
| GET | /actuator/conditions | 查看自動配置的結果,記錄哪些自動配置條件通過了,哪些沒通過 |
| GET | /actuator/configprops | 查看注入帶有 @ConfigurationProperties 類的 properties 值為何(包含默認值) |
| GET | /actuator/env (常用) | 查看全部環境屬性,可以看到 SpringBoot 載入了哪些 properties,以及這些 properties 的值(但是會自動*掉帶有 key、password、secret 等關鍵字的 properties 的值,保護安全資訊) |
| GET | /actuator/flyway | 查看 flyway DB 的 migration 資訊 |
| GET | /actuator/health (常用) | 查看當前 SpringBoot 運行的健康指標,值由 HealthIndicator 的實現類提供(所以可以自定義一些健康指標資訊,加到這裡面) |
| GET | /actuator/heapdump | 取得 JVM 當下的 heap dump,會下載一個檔案 |
| GET | /actuator/info | 查看 properties 中 info 開頭的屬性的值,沒啥用 |
| GET | /actuator/mappings | 查看全部的 endpoint(包含 Actuator 的),以及他們和 Controller 的關係 |
| GET | /actuator/metrics(常用) | 查看有哪些指標可以看(ex: jvm.memory.max、system.cpu.usage),要再使用/actuator/metrics/{metric.name}分別查看各指標的詳細資訊 |
| GET | /actuator/scheduledtasks | 查看定時任務的資訊 |
| POST | /actuator/shutdown | 唯一一個需要 POST 請求的 endpoint,關閉這個 SpringBoot 程式 |
四、端點配置
- 默認暴露
我們可以通過以下配置,來配置通過JMX 和 HTTP 暴露的端點。
| Property | Default |
|---|---|
management.endpoints.jmx.exposure.exclude |
|
management.endpoints.jmx.exposure.include |
* |
management.endpoints.web.exposure.exclude |
|
management.endpoints.web.exposure.include |
info, healt |
因為安全的因素,所以 Actuator 默認只會開放/actuator/health和/actuator/info這兩個 endpoint,如果要開放其他 endpoint 的話,需要額外在 application.properties 中做設置。
- 暴露配置
# 可以這樣寫,就會開啟所有endpoints(不包含shutdown) management.endpoints.web.exposure.include=* # 也可以這樣寫,就只會開啟指定的endpoint,因此此處只會再額外開啟/actuator/beans和/actuator/mappings management.endpoints.web.exposure.include=beans,mappings # exclude可以用來關閉某些endpoints # exclude通常會跟include一起用,就是先include了全部,然後再exclude /actuator/beans這個endpoint management.endpoints.web.exposure.exclude=beans management.endpoints.web.exposure.include=* # 如果要開啟/actuator/shutdown,要額外再加這一行 management.endpoint.shutdown.enabled=true
- 路徑映射
默認情況下所有端點都暴露在“/actuator”路徑下,也可以改變/actuator的路徑,可以自定義成自己想要的:
#這樣寫的話,原本內建的/actuator/xxx路徑,都會變成/manage/xxx,可以用來防止被其他人猜到 management.endpoints.web.base-path=/manage
#同時可以將health修改成healthcheck
management.endpoints.web.path-mapping.health=healthcheck
- 管理端口調整
#指定端口,默認跟server.port一樣,可以防止被其他人猜到 management.server.port=10111
- 端點響應緩存
對於一些不帶參數的端點請求會自動進行緩存,我們可以通過如下方式配置緩存時間,下面配置表示 beans 端點的緩存時間為 100s
management.endpoint.beans.cache.time-to-live=100s
五、端點保護
如果開啟了 Actuator 默認不打開的 endpoints,建議一定要加上 Spring security 之類的做 endpoint 保護,避免重要資訊外洩。因為端點的信息和產生的交互都是非常敏感的,必須防止未經授權的外部訪問。
這里我們使用 Spring Security 保護,首先添加相關依賴:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
添加之后,我們需要定義安全校驗規則,來覆蓋Spring Security 的默認配置。
這里我給出了兩個版本的模板配置:
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 { /* * version1: * 1. 限制 '/shutdown'端點的訪問,只允許ACTUATOR訪問 * 2. 允許外部訪問其他的端點 * 3. 允許外部訪問靜態資源 * 4. 允許外部訪問 '/' * 5. 其他的訪問需要被校驗 * version2: * 1. 限制所有端點的訪問,只允許ACTUATOR訪問 * 2. 允許外部訪問靜態資源 * 3. 允許外部訪問 '/' * 4. 其他的訪問需要被校驗 */ @Override protected void configure(HttpSecurity http) throws Exception { // version1 // http // .authorizeRequests() // .requestMatchers(EndpointRequest.to(ShutdownEndpoint.class)) // .hasRole("ADMIN") // .requestMatchers(EndpointRequest.toAnyEndpoint()) // .permitAll() // .requestMatchers(PathRequest.toStaticResources().atCommonLocations()) // .permitAll() // .antMatchers("/") // .permitAll() // .antMatchers("/**") // .authenticated() // .and() // .httpBasic(); // version2 http .authorizeRequests() .requestMatchers(EndpointRequest.toAnyEndpoint()) .hasRole("ADMIN") .requestMatchers(PathRequest.toStaticResources().atCommonLocations()) .permitAll() .antMatchers("/") .permitAll() .antMatchers("/**") .authenticated() .and() .httpBasic(); } }
application.properties的相關配置如下:
# Spring Security Default user name and password
spring.security.user.name=actuator spring.security.user.password=actuator spring.security.user.roles=ADMIN
六、重要端點解析
/health 端點
-
/health配置
當我們開啟health的健康端點時,我們能夠查到應用健康信息是一個匯總的信息,訪問 http://127.0.0.1:10111/actuator/health時,我們獲取到的信息是{"status":"UP"},status的值還有可能是 DOWN。
management.endpoint.health.show-details=always
- never:不展示詳細信息,up或者down的狀態,默認配置
- when-authorized:詳細信息將會展示給通過認證的用戶。授權的角色可以通過
management.endpoint.health.roles配置 - always:對所有用戶暴露詳細信息
always之后,我們啟動項目再次訪問
http://127.0.0.1:10111/actuator/health,獲取的信息如下:
{ "status": "UP", "details": { "diskSpace": { "status": "UP", "details": { "total": 250685575168, "free": 172252426240, "threshold": 10485760 } }, "redis": { "status": "UP", "details": { "version": "3.2.11" } }, "db": { "status": "UP", "details": { "database": "Oracle", "hello": "Hello" } } } }
/health端點有很多自動配置的健康指示器:如redis、rabbitmq、db等組件。當你的項目有依賴對應組件的時候,這些健康指示器就會被自動裝配,繼而采集對應的信息。
如上面的 diskSpace 節點信息就是DiskSpaceHealthIndicator 在起作用。

上述截圖取自官方文檔。
management.health.mongo.enabled: false
或者禁用所有自動配置的健康指示器:
management.health.defaults.enabled: false
/health原理
ApplicationContext中的各種
HealthIndicator Beans中收集到的,Spring boot框架中包含了大量的
HealthIndicators的實現類,當然你也可以實現自己認為的健康狀態。
HealthAggregator匯總而成的,匯總的算法是:
- 設置狀態碼順序:
setStatusOrder(Status.DOWN, Status.OUT_OF_SERVICE, Status.UP, Status.UNKNOWN)。 - 過濾掉不能識別的狀態碼。
- 如果無任何狀態碼,整個spring boot應用的狀態是
UNKNOWN。 - 將所有收集到的狀態碼按照 1 中的順序排序。
- 返回有序狀態碼序列中的第一個狀態碼,作為整個spring boot應用的狀態。
源代碼請參見:
org.springframework.boot.actuate.health.OrderedHealthAggregator。
HealthIndicators 目前包括:
| Name | Description |
|---|---|
CassandraHealthIndicator |
Checks that a Cassandra database is up. |
DiskSpaceHealthIndicator |
Checks for low disk space. |
DataSourceHealthIndicator |
Checks that a connection to DataSource can be obtained. |
ElasticsearchHealthIndicator |
Checks that an Elasticsearch cluster is up. |
InfluxDbHealthIndicator |
Checks that an InfluxDB server is up. |
JmsHealthIndicator |
Checks that a JMS broker is up. |
MailHealthIndicator |
Checks that a mail server is up. |
MongoHealthIndicator |
Checks that a Mongo database is up. |
Neo4jHealthIndicator |
Checks that a Neo4j server is up. |
RabbitHealthIndicator |
Checks that a Rabbit server is up. |
RedisHealthIndicator |
Checks that a Redis server is up. |
SolrHealthIndicator |
Checks that a Solr server is up. |
management.health.defaults.enabled這個配置項將它們全部禁用掉,也可以通過
management.health.xxxx.enabled將其中任意一個禁用掉。
- 自定義 HealthIndicator
HealthIndicator的接口來實現,並將該實現類注冊為spring bean。
health()方法,並返回自定義的健康狀態響應信息,該響應信息應該包括一個狀態碼和要展示詳細信息。
HealthIndicator的實現類:
import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.stereotype.Component; @Component public class MyHealthIndicator implements HealthIndicator { @Override public Health health() { int errorCode = check(); // perform some specific health check if (errorCode != 0) { return Health.down().withDetail("Error Code", errorCode).build(); } return Health.up().build(); } }
HealthAggregator ,或者通過配置
management.health.status.order 來繼續使用
HealthAggregator的默認實現。
HealthIndicator的實現類中,使用了自定義的狀態類型
FATAL,為了配置該狀態類型的嚴重程度,你需要在application的配置文件中添加如下配置:
management.health.status.order=FATAL, DOWN, OUT_OF_SERVICE, UNKNOWN, UP
UP 對應 200, 而
OUT_OF_SERVICE 和
DOWN 對應 503)。
FATAL 映射為 503(服務不可用):
management.health.status.http-mapping.FATAL=503
如果你需要更多的控制,你可以定義自己的 HealthStatusHttpMapper bean。
下面是內置健康狀態類型對應的HTTP狀態碼列表:
| Status | Mapping |
|---|---|
| DOWN | SERVICE_UNAVAILABLE (503) |
| OUT_OF_SERVICE | SERVICE_UNAVAILABLE (503) |
| UP | No mapping by default, so http status is 200 |
| UNKNOWN | No mapping by default, so http status is 200 |
/metrics 端點
- 查看所有可追蹤的度量
/metrics端點用來返回當前應用的各類重要度量指標,比如:內存信息、線程信息、垃圾回收信息、tomcat、數據庫連接池等。
{ "names": [ "hikaricp.connections", "hikaricp.connections.acquire", "hikaricp.connections.active", "hikaricp.connections.creation", "hikaricp.connections.idle", "hikaricp.connections.max", "hikaricp.connections.min", "hikaricp.connections.pending", "hikaricp.connections.timeout", "hikaricp.connections.usage", "jvm.buffer.count", "jvm.buffer.memory.used", "jvm.buffer.total.capacity", "jvm.classes.loaded", "jvm.classes.unloaded", "jvm.gc.live.data.size", "jvm.gc.max.data.size", "jvm.gc.memory.allocated", "jvm.gc.memory.promoted", "jvm.gc.pause", "jvm.memory.committed", "jvm.memory.max", "jvm.memory.used", "jvm.threads.daemon", "jvm.threads.live", "jvm.threads.peak", "jvm.threads.states", "logback.events", "process.cpu.usage", "process.start.time", "process.uptime", "system.cpu.count", "system.cpu.usage", "tomcat.cache.access", "tomcat.cache.hit", "tomcat.global.error", "tomcat.global.received", "tomcat.global.request", "tomcat.global.request.max", "tomcat.global.sent", "tomcat.servlet.error", "tomcat.servlet.request", "tomcat.servlet.request.max", "tomcat.sessions.active.current", "tomcat.sessions.active.max", "tomcat.sessions.alive.max", "tomcat.sessions.created", "tomcat.sessions.expired", "tomcat.sessions.rejected", "tomcat.threads.busy", "tomcat.threads.config.max", "tomcat.threads.current", "zipkin.reporter.messages", "zipkin.reporter.messages.total", "zipkin.reporter.queue.bytes", "zipkin.reporter.queue.spans", "zipkin.reporter.spans", "zipkin.reporter.spans.dropped", "zipkin.reporter.spans.total" ] }
各個指標說明如下:
| 序號 | 參數 | 參數說明 | 是否監控 | 監控手段 | 重要度 |
|---|---|---|---|---|---|
| JVM | |||||
| 1 | jvm.memory.max | JVM 最大內存 | |||
| 2 | jvm.memory.committed | JVM 可用內存 | 是 | 展示並監控堆內存和 Metaspace | 重要 |
| 3 | jvm.memory.used | JVM 已用內存 | 是 | 展示並監控堆內存和 Metaspace | 重要 |
| 4 | jvm.buffer.memory.used | JVM 緩沖區已用內存 | |||
| 5 | jvm.buffer.count | 當前緩沖區數 | |||
| 6 | jvm.threads.daemon | JVM 守護線程數 | 是 | 顯示在監控頁面 | |
| 7 | jvm.threads.live | JVM 當前活躍線程數 | 是 | 顯示在監控頁面;監控達到閾值時報警 | 重要 |
| 8 | jvm.threads.peak | JVM 峰值線程數 | 是 | 顯示在監控頁面 | |
| 9 | jvm.classes.loaded | 加載 classes 數 | |||
| 10 | jvm.classes.unloaded | 未加載的 classes 數 | |||
| 11 | jvm.gc.memory.allocated | GC 時,年輕代分配的內存空間 | |||
| 12 | jvm.gc.memory.promoted | GC 時,老年代分配的內存空間 | |||
| 13 | jvm.gc.max.data.size | GC 時,老年代的最大內存空間 | |||
| 14 | jvm.gc.live.data.size | FullGC 時,老年代的內存空間 | |||
| 15 | jvm.gc.pause | GC 耗時 | 是 | 顯示在監控頁面 | |
| TOMCAT | |||||
| 16 | tomcat.sessions.created | tomcat 已創建 session 數 | |||
| 17 | tomcat.sessions.expired | tomcat 已過期 session 數 | |||
| 18 | tomcat.sessions.active.current | tomcat 活躍 session 數 | |||
| 19 | tomcat.sessions.active.max | tomcat 最多活躍 session 數 | 是 | 顯示在監控頁面,超過閾值可報警或者進行動態擴容 | 重要 |
| 20 | tomcat.sessions.alive.max.second | tomcat 最多活躍 session 數持續時間 | |||
| 21 | tomcat.sessions.rejected | 超過 session 最大配置后,拒絕的 session 個數 | 是 | 顯示在監控頁面,方便分析問題 | |
| 22 | tomcat.global.error | 錯誤總數 | 是 | 顯示在監控頁面,方便分析問題 | |
| 23 | tomcat.global.sent | 發送的字節數 | |||
| 24 | tomcat.global.request.max | request 最長時間 | |||
| 25 | tomcat.global.request | 全局 request 次數和時間 | |||
| 26 | tomcat.global.received | 全局 received 次數和時間 | |||
| 27 | tomcat.servlet.request | servlet 的請求次數和時間 | |||
| 28 | tomcat.servlet.error | servlet 發生錯誤總數 | |||
| 29 | tomcat.servlet.request.max | servlet 請求最長時間 | |||
| 30 | tomcat.threads.busy | tomcat 繁忙線程 | 是 | 顯示在監控頁面,據此檢查是否有線程夯住 | |
| 31 | tomcat.threads.current | tomcat 當前線程數(包括守護線程) | 是 | 顯示在監控頁面 | 重要 |
| 32 | tomcat.threads.config.max | tomcat 配置的線程最大數 | 是 | 顯示在監控頁面 | 重要 |
| 33 | tomcat.cache.access | tomcat 讀取緩存次數 | |||
| 34 | tomcat.cache.hit | tomcat 緩存命中次數 | |||
| CPU | |||||
| 35 | system.cpu.count | CPU 數量 | |||
| 36 | system.load.average.1m | load average | 是 | 超過閾值報警 | 重要 |
| 37 | system.cpu.usage | 系統 CPU 使用率 | |||
| 38 | process.cpu.usage | 當前進程 CPU 使用率 | 是 | 超過閾值報警 | |
| 39 | http.server.requests | http 請求調用情況 | 是 | 顯示 10 個請求量最大,耗時最長的 URL;統計非 200 的請求量 | 重要 |
| 40 | process.uptime | 應用已運行時間 | 是 | 顯示在監控頁面 | |
| 41 | process.files.max | 允許最大句柄數 | 是 | 配合當前打開句柄數使用 | |
| 42 | process.start.time | 應用啟動時間點 | 是 | 顯示在監控頁面 | |
| 43 | process.files.open | 當前打開句柄數 | 是 | 監控文件句柄使用率,超過閾值后報警 | 重要 |
- 查看某個度量的詳細信息
不同於1.x,Actuator在這個界面看不到具體的指標信息,只是展示了一個指標列表。為了獲取到某個指標的詳細信息,我們可以請求具體的指標信息,像這樣:
http://localhost:8080/actuator/metrics/{MetricName}
比如我訪問/actuator/metrics/jvm.memory.max,返回信息如下:

你也可以用query param的方式查看單獨的一塊區域。比如你可以訪問/actuator/metrics/jvm.memory.max?tag=id:Metaspace。結果就是:

- 添加自定義統計指標
1,Gauge(計量器)
Gauge(計量器)是最簡單的度量類型,只有一個簡單的返回值,他用來記錄一些對象或者事物的瞬時值。
@RestController public class HelloController { @GetMapping("/hello") public void hello() { Metrics.gauge("user.test.gauge", 3); } }
(2)通過 /actuator/metrics 接口可以看到我們自定義的這個指標:
2,Counter(計數器)
Counter(計數器)簡單理解就是一種只增不減的計數器。它通常用於記錄服務的請求數量、完成的任務數量、錯誤的發生數量等等。
(1)為方便使用首先我們自定義一個計數器服務:
@Service public class MyCounterService { static final Counter userCounter = Metrics.counter("user.counter.total", "services", "demo"); public void processCollectResult() { userCounter.increment(1D); } }
(2)然后增加一個 controller,觸發這個服務:
@RestController public class HelloController { @Autowired MyCounterService myCounterService; @GetMapping("/hello") public void hello() { myCounterService.processCollectResult(); } }
(3)通過 /actuator/metrics 接口可以看到我們自定義的這個指標:
(4)假設我們訪問了 3 次 /hello 接口,再次通過 /actuator/metrics/user.counter.total 這個自定義度量的消息信息,顯示如下:
3,Timer(計時器)
Timer(計時器)可以同時測量一個特定的代碼邏輯塊的調用(執行)速度和它的時間分布。
簡單來說,就是在調用結束的時間點記錄整個調用塊執行的總時間,適用於測量短時間執行的事件的耗時分布,例如消息隊列消息的消費速率。
(1)假設我們在一個 Contoller 使用 Timer 來記錄某個方法的執行時長:
注意:在實際生產環境中,可以通過 spring-aop 把記錄方法耗時的邏輯抽象到一個切面中,這樣就能減少不必要的冗余的模板代碼。
@RestController public class HelloController { private Timer timer = Metrics.timer("user.test.timer","timer", "timersample"); @GetMapping("/hello") public void hello() { // 執行createOrder方法並記錄執行時間 timer.record(() -> createOrder()); } //模擬方法耗時 private void createOrder() { try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { } } }
(2)假設我們訪問了 3 次 /hello 接口,再次通過 /actuator/metrics/user.test.timer 這個自定義度量的消息信息,顯示如下:
4,Summary(摘要)
Summary(摘要)用於跟蹤事件的分布。它類似於一個計時器,但更一般的情況是,它的大小並不一定是一段時間的測量值。
在 micrometer 中,對應的類是 DistributionSummary,它的用法有點像 Timer,但是記錄的值是需要直接指定,而不是通過測量一個任務的執行時間。
(1)假設我們在一個 Contoller 使用 Summary 來連續記錄三次值:
@RestController public class HelloController { private DistributionSummary summary = Metrics.summary("user.test.summary","summary", "summarysample"); @GetMapping("/hello") public void hello() { summary.record(2D); summary.record(3D); summary.record(4D); } }
(2)假設我們訪問 /hello 接口后,再次通過 /actuator/metrics/user.test.summary 這個自定義度量的消息信息,顯示如下:
/loggers 端點
- 查看日志等級
/loggers 端點暴露了我們程序內部配置的所有logger的信息。我們訪問/actuator/loggers可以看到:

你也可以通過下述方式訪問單獨一個logger:
http://localhost:8080/actuator/loggers/{name}
比如我現在訪問 root logger,http://localhost:8080/actuator/loggers/root:
{ "configuredLevel": "INFO", "effectiveLevel": "INFO" }
- 改變運行時日志等級
/loggers端點能夠動態修改你的日志等級。
比如,我們可以通過下述方式來修改 root logger的日志等級。我們只需要發起一個URL 為http://localhost:8080/actuator/loggers/root的POST請求,POST報文如下:
{ "configuredLevel": "DEBUG" }

仔細想想,這個功能是不是非常有用。如果在生產環境中,你想要你的應用輸出一些Debug信息以便於你診斷一些異常情況,你只需要按照上述方式就可以修改,而不需要重啟應用。
如果想重置成默認值,把value 改成
null
/info 端點
/info端點可以用來展示應用信息,主要包含三大類:自定義信息、Git 信息、以及項目構建信息。下面主要介紹自定義信息。
(1)自定義信息可以在 application.properties 配置文件中添加,這些以 info 開頭的信息將在 info 端點中顯示出來:
info.app.name=actuator-test-demo info.app.encoding=UTF-8 info.app.java.source=1.8 info.app.java.target=1.8
啟動項目,訪問http://localhost:8080/actuator/info:
{ "app": { "encoding": "UTF-8", "java": { "source": "1.8.0_131", "target": "1.8.0_131" }, "name": "actuator-test-demo" } }
(2)我們也可以通過 Java 代碼自定義信息,只需要將自定義類繼承自 InfoContributor,然后實現該類中的 contribute 方法即可:
@Component public class MyInfo implements InfoContributor { @Override public void contribute(Info.Builder builder) { Map<String, String> info = new HashMap<>(); info.put("name", "航歌"); info.put("email", "service@hangge.com"); builder.withDetail("author", info); } }

/beans 端點
/beans端點會返回Spring 容器中所有bean的別名、類型、是否單例、依賴等信息。
訪問http://localhost:8080/actuator/beans,返回如下:

/heapdump 端點
訪問:http://localhost:8080/actuator/heapdump會自動生成一個 Jvm 的堆文件 heapdump。我們可以使用 JDK 自帶的 Jvm 監控工具 VisualVM 打開此文件查看內存快照。

/threaddump 端點
http://localhost:8080/actuator/threaddump返回如下:
這個端點屬於操作控制類端點,可以優雅關閉 Spring Boot 應用。要使用這個功能首先需要在配置文件中開啟:
management.endpoint.shutdown.enabled=true
由於 shutdown 接口默認只支持 POST 請求,我們啟動Demo項目,發起POST請求:
curl -X "POST" "http://localhost:8080/actuator/shutdown"
返回信息:
{ "message": "Shutting down, bye..." }
然后應用程序被關閉。類似停服的操作還有很多,比如restart、pause等。可根據具體版本進行配置。
由於開放關閉應用的操作本身是一件非常危險的事,所以真正在線上使用的時候,我們需要對其加入一定的保護機制,
比如:定制Actuator的端點路徑、整合Spring Security進行安全校驗等。(不是特別必要的話,這個端點不用開)。
定制Actuator的端點路徑和端口:
-
management.endpoints.web.base-path 自定義shutdown的請求路徑;
-
management.server.address 設置為本地ip,防止遠程訪問該連接進行關閉服務;
-
management.server.port 自定義shutdown請求路徑的端口號;
調整后的配置文件如下:
management: endpoint: shutdown: enabled: true endpoints: web: exposure: include: '*' jmx: exposure: include: '*' server: # 自定義端口 port: 8888 # 不允許遠程管理連接,安全性考慮 address: 127.0.0.1
七、自定義Endpoint
默認的端點雖然可以滿足大多數的需求,但一些特殊的需求還是需要能夠支持自定義端點的。
自定義 Endpoint 端點,只需要在我們的新建Bean上使用 @Endpoint 注解即可, Bean 中的方法就可以通過 JMX 或者 HTTP 公開。
除此之外,還可以使用 @JmxEndpoint 或 @WebEndpoint 編寫 EndPoint。但這些 EndPoint 僅限於各自的公開方式。例如,@WebEndpoint 僅通過HTTP公開,而不通過JMX公開。
那么是不是類中所有的方法都支持對外公開呢?
很明顯不是的。Actuator提供了三個用於方法上的注解,只有加三個注解的方法才支持對外公開,並且每個注解都有支持它的HTTP method。
- @ReadOperation對應HTTP的GET請求
- @WriteOperation對應HTTP的POST請求
- @DeleteOperation對應HTTP的DELETE請求
來看一個簡單的使用實例:
@Component @Endpoint(id = "my") public class EndpointCustom { @ReadOperation public String endpointCustomRead(String content) { return "請求的內容: " + content; } @WriteOperation public String endpointCustomWrite(String content) { return "寫的內容: " + content; } @DeleteOperation public String endpointCustomDelete(String content) { return "刪除的內容: " + content; } }
對應GET請求:
curl -X GET http://localhost:8080/actuator/my?content=endpointGet
執行之后,會返回信息“請求的內容: endpointGet”。
同樣的POST請求為:
curl -X POST http://localhost:8080/actuator/my?content=endpointPost
DELETE請求為:
curl -X DELETE http://localhost:8080/actuator/my?content=endpointDELETE
上面只是簡單自定義實例,根據具體的業務場景,可以定義更加豐富的端點實現。
