SpringBoot Actuator
- 一、簡介
- 二、入門
- 1、依賴
- 2、默認監控指標
- 3、查詢監控指標
- 4、全量監控指標
- 三、Spring Boot Admin
- 1、主要功能
- 2、Admin
- 3、Client
- 4、應用墻
- 5、其他
- 四、定制化
- 1、定制Health端點
- 2、定制Info端點
- 3、定制Metrics端點
- 4、定制Endpoint端點
一、簡介
SpringBoot自帶監控功能Actuator,可以幫助實現對程序內部運行情況監控,比如監控狀況、Bean加載情況、環境變 量、日志信息、線程信息等
二、入門
1、依賴
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>
2、默認監控指標
需要啟動應用項目
訪問方式一:HTTP形式

訪問方式二:jconsole形式

在默認配置情況下,使用jconsole訪問會顯示暴露出來的其他接口
3、查詢監控指標
直接訪問對應的href地址即可

jconsole直接點擊可視化界面即可
4、全量監控指標
修改配置文件
management.endpoints.web.exposure.include=*

常用指標說明:
- beans:Spring容器中的Bean信息
- caches:應用中的緩存
- health:現實健康檢查信息
- info:顯示設置好的應用信息
- conditions:Spring Boot的條件逐漸
- configprops:Spring的配置類
- env:返回當前環境屬性(Environment Properties)
- loggers:能夠查詢和修改應用的日志級別。
- heapdump:會構建并返回應用所用 JVM 的 Heap Dump。
- threaddump:會 Dump 底層 JVM 的線程信息
- metrics:詳細介紹了應用的指標。這可能包括通用指標和自定義指標。
- scheduledtasks:提供了應用中每個計劃(定時)任務的詳細信息。
- prometheus:返回可供Prometheus抓取的信息
三、Spring Boot Admin
Spring Boot Admin 是一個用于管理和監控 Spring Boot 應用程序的開源項目。它提供了一個簡單易用的 Web 界面,讓開發者可以方便地查看和管理多個 Spring Boot 應用實例的運行狀態、健康狀況、配置信息等。
1、主要功能
- 應用程序發現與注冊:Spring Boot Admin 支持通過 Spring Cloud Discovery(如 Eureka、Consul 等)自動發現注冊的 Spring Boot 應用程序,也可以通過 HTTP 進行手動注冊。
- 健康監控:實時顯示應用程序的健康狀態,包括磁盤空間、數據庫連接、緩存狀態等。可以通過
/actuator/health
端點獲取詳細的健康信息。 - 指標監控:收集和展示應用程序的各種指標,如內存使用情況、線程池狀態、HTTP 請求統計等。這些指標通過
/actuator/metrics
端點暴露。 - 日志管理:允許查看和管理應用程序的日志文件,支持實時日志查看和日志級別調整。可以通過
/actuator/logfile
和/actuator/loggers
端點進行操作。 - 環境與配置信息:顯示應用程序的環境變量、系統屬性和配置信息,方便開發者查看和調試。
- 事件與通知:當應用程序的狀態發生變化(如上線、下線、健康狀態改變等)時,Spring Boot Admin 可以發送通知,支持多種通知方式,如郵件、Slack、HipChat 等。
2、Admin
注意版本需要和項目的Spring Boot版本對齊,否則無法正常訪問
1)添加依賴
<dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-server</artifactId><version>2.6.6</version>
</dependency>
2)啟動類添加@EnableAdminServer
3)訪問

3、Client
1)引入依賴
<dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-client</artifactId><version>3.3.4</version>
</dependency>
2)配置注冊地址
## 地址是admin的訪問地址
spring.boot.admin.client.url=http://localhost:8088
management.endpoints.web.exposure.include=*
3)啟動項目
admin端會出現注冊者,這個注冊者就是我們的client端

4、應用墻
此時就可以查看到我們client端的數據指標了

當client端下線后,對應的應用塊會有顏色警示

5、其他
我們每個Client端都需要去這么配置會十分繁瑣,我們的admin端可以直接監控注冊中心,遍歷注冊中心所有的項目,獲取對應的監控數據。
而對應的client端只需要暴露對應的端點即可,即引入依賴&配置暴露端點
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>
</dependencies>
management.endpoints.web.exposure.include=*
四、定制化
1、定制Health端點
- CustomHealthIndicator 類實現了 HealthIndicator 接口。
- health() 方法根據 isHealthy 變量的值返回不同的健康狀態。如果 isHealthy 為 true,則返回 Health.up() 表示健康;否則返回 Health.down() 表示不健康。
- withDetail() 方法用于添加自定義的詳細信息到健康檢查結果中。
package pers.mobian.springbootactuatordemo.indicator;import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;@Component
public class CustomHealthIndicator implements HealthIndicator {private static final String CUSTOM_STATUS_KEY = "customStatus";private boolean isHealthy = false;// 模擬切換健康狀態的方法public void setHealthy(boolean healthy) {isHealthy = healthy;}@Overridepublic Health health() {if (isHealthy) {return Health.up().withDetail(CUSTOM_STATUS_KEY, "Everything is running smoothly.").build();} else {return Health.down().withDetail(CUSTOM_STATUS_KEY, "There is an issue with the custom service.").build();}}
}
此時訪問health接口,就會因為CustomHealthIndicator這個端點校驗不通過,而返回DOWN

2、定制Info端點
- CustomInfoContributor 類實現了 InfoContributor 接口。
- contribute 方法用于向 Info.Builder 中添加自定義信息,這里添加了當前時間和一個隨機事實。
package pers.mobian.springbootactuatordemo.indicator;import org.springframework.boot.actuate.info.Info;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;@Component
public class CustomInfoContributor implements InfoContributor {@Overridepublic void contribute(Info.Builder builder) {String currentTime = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);builder.withDetail("currentTime", currentTime).withDetail("randomFact", "Spring Boot is awesome!");}
}
訪問info接口,就會出現我們添加的信息

3、定制Metrics端點
1)引入依賴
<!-- Micrometer 是 Spring Boot Actuator 底層的指標收集庫 -->
<dependency><groupId>io.micrometer</groupId><artifactId>micrometer-core</artifactId>
</dependency>
2)自定義端點
- CustomMetricsService 類借助 MeterRegistry 創建了一個名為 custom.operation.count 的計數器。
- incrementCustomCounter 方法用于增加計數器的值。
package pers.mobian.springbootactuatordemo.indicator;import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.stereotype.Service;@Service
public class CustomMetricsService {private final MeterRegistry meterRegistry;private Counter customCounter;public CustomMetricsService(MeterRegistry meterRegistry) {this.meterRegistry = meterRegistry;customCounter = meterRegistry.counter("custom.operation.count");}public void incrementCustomCounter() {// 每次調用該方法時,計數器加 1customCounter.increment();}
}
3)計數器累加接口
創建一個控制器來觸發自定義指標的更新
package pers.mobian.springbootactuatordemo.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import pers.mobian.springbootactuatordemo.indicator.CustomMetricsService;@RestController
public class CustomMetricsController {@Autowiredprivate CustomMetricsService customMetricsService;@GetMapping("/perform-operation")public String performOperation() {// 執行操作時,調用計數器增加方法customMetricsService.incrementCustomCounter();return "Operation performed and counter incremented.";}
}
4)瀏覽器訪問
增加計數器:http://127.0.0.1:8080/perform-operation

查詢計數指標::http://127.0.0.1:8080/actuator/metrics/custom.operation.count

5)定制指標過濾器
可以通過配置 MeterFilter`來過濾不需要的指標或者對指標進行重命名等操作。它會拒絕所有以 jvm. 開頭的指標,這樣這些指標就不會出現在 metrics 端點的響應中。
import io.micrometer.core.instrument.config.MeterFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MetricsConfig {@Beanpublic MeterFilter ignoreMetricsFilter() {return MeterFilter.denyNameStartsWith("jvm.");}
}
4、定制Endpoint端點
1)只讀customEndpoint
- @Component:將該類注冊為 Spring Bean。
- @Endpoint(id = “customEndpoint”):標記該類為一個 Actuator 端點,id 是端點的唯一標識符。
- @ReadOperation:表示該方法是一個只讀操作,用于返回端點的數據
package pers.mobian.springbootactuatordemo.indicator;import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.Map;@Component
@Endpoint(id = "customEndpoint")
public class CustomEndpoint {@ReadOperationpublic Map<String, String> customInfo() {Map<String, String> info = new HashMap<>();info.put("message", "This is a custom endpoint in Spring Boot 3.x.");info.put("version", "1.0");return info;}
}

2)讀寫端點advancedCustomEndpoint
package pers.mobian.springbootactuatordemo.indicator;import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;import java.util.HashMap;
import java.util.Map;@Component
@Endpoint(id = "advancedCustomEndpoint")
public class AdvancedCustomEndpoint {private final Map<String, String> data = new HashMap<>();@ReadOperationpublic Map<String, String> getData() {return data;}@WriteOperation@RequestMapping(consumes = MediaType.APPLICATION_JSON_VALUE)public void addData(String key, String value) {data.put(key, value);}@DeleteOperationpublic void deleteData(String key) {data.remove(key);}
}
使用jconsole發送寫請求

瀏覽器訪問,查詢寫入的數據
