不知道大家在寫 Spring Boot
項目的過程中,使用過 Spring Boot Actuator
嗎?知道 Spring Boot Actuator
是什么,干什么的嗎?今天就要來給大家介紹一下 Spring Boot Actuator
,學習如何在 Spring Boot 2.x
中使用、配置和擴展這個監(jiān)控工具。Spring Boot 1.x
的使用就不再這邊介紹了。相信大家平時使用的框架基本上都要升級到 2.x了吧。
什么是 Actuator ?
從本質(zhì)上講,Spring Boot Actuator
為我們的應(yīng)用程序帶來了生產(chǎn)就緒的功能。監(jiān)控我們的應(yīng)用程序,收集指標,了解流量,或者是數(shù)據(jù)庫的狀態(tài)。有了它,我們就可以很簡單的監(jiān)控應(yīng)用程序的各種指標數(shù)據(jù)。
Spring Boot Actuator
使用 http 或者 JMX 的方式來公開運行中的應(yīng)用程序的操作信息--健康、指標、信息、轉(zhuǎn)儲、環(huán)境等,我們能夠方便的與它互動。只要添加Spring Boot Actuator
依賴到 classpath 中,就有幾個指標路徑可供我們開箱使用。與大多數(shù) Spring boot
模塊一樣,我們可以很容易地以多種方式配置或擴展它。
快速入門
要想啟用 Spring Boot Actuator
,我們只需在軟件包管理器中添加 spring-boot-starter-actuator
依賴項。在 pom.xml
文件添加如下代碼即可:
< dependency >
< groupId >org.springframework.boot< /groupId >
< artifactId >spring-boot-starter-actuator< /artifactId >
< /dependency >
是吧,很簡單就添加好了。有的小朋友可能會有疑問了,為什么沒有添加 version
節(jié)點呢?那是因為 Spring Boot
的 parent pom
會制定版本號,所以這里無需再次指定了。
Spring Boot 2.x Actuator
在 2.x
版本中,Spring Boot Actuator
保持了 1.x
的基本操作,但簡化了它的模型,擴展了它的能力,并加入了更好的默認值。這個版本變得與技術(shù)無關(guān)。它還簡化了其安全模型,將其與應(yīng)用程序模型合并。最新版本現(xiàn)在支持CRUD模型,而不是舊的讀寫模型。
技術(shù)支持
在 2.x
中,Spring Boot Actuator
將其模型定義為可插拔和可擴展的,而不依賴于 MVC。通過這個新的模型,我們能夠利用 MVC 以及 WebFlux 作為底層 Web 技術(shù)的優(yōu)勢。此外,可以通過實現(xiàn)正確的適配器來添加即將到來的技術(shù)。不過 JMX 仍然被支持,無需任何額外的代碼就可以暴露路徑。
重要變化
與以前的版本不同,Spring Boot Actuator
的大多數(shù)路徑都是禁用的。默認情況下,只有 /health
和 /info
兩個可用。如果我們想啟用所有的路徑,可以設(shè)置 management.endpoints.web.exposure.include=*
來實現(xiàn)。Actuator
現(xiàn)在與常規(guī)的 App
安全規(guī)則共享安全配置,所以安全模型被大大簡化。要調(diào)整 Actuator
的安全規(guī)則,我們可以只添加一個 /actuator/**
的條目。
@Bean
public SecurityWebFilterChain securityWebFilterChain(
ServerHttpSecurity http) {
return http.authorizeExchange()
.pathMatchers("/actuator/**").permitAll()
.anyExchange().authenticated()
.and().build();
}
我們可以在全新的 Actuator
官方文檔中找到進一步的細節(jié)。另外,在默認情況下,所有的 Actuator
路徑現(xiàn)在都被放在 /actuator
路徑下。和以前的版本一樣,我們可以使用新的屬性management.endpoints.web.base-path
來調(diào)整這個路徑。
預定義的路徑
讓我們看看一些可用的路徑,其中大部分在1.x中已經(jīng)可用。另外,有些路徑被添加了,有些被刪除了,有些被重組了。
- /auditevents 列出了安全審計相關(guān)的事件,如用戶登錄/注銷。此外,我們還可以通過本金或類型以及其他字段進行過濾。
- /beans 返回我們BeanFactory中所有可用的bean。與/auditevents不同,它不支持過濾。
- /conditions,以前被稱為/autoconfig,圍繞自動配置建立一個條件報告。
- /configprops 允許我們獲取所有@ConfigurationProperties。
- /env 返回當前的環(huán)境屬性。此外,我們還可以檢索單個屬性。
- /flyway 提供了關(guān)于我們Flyway數(shù)據(jù)庫遷移的細節(jié)。
- /health 總結(jié)了我們應(yīng)用程序的健康狀態(tài)。
- /heapdump 構(gòu)建并返回我們應(yīng)用程序使用的 JVM 的堆存儲。
- /info 返回一般信息。它可能是自定義數(shù)據(jù)、構(gòu)建信息或關(guān)于最新提交的細節(jié)。
- /liquibase 的行為類似于/flyway,但針對Liquibase。
- /logfile 返回普通的應(yīng)用程序日志。
- /loggers 使我們能夠查詢和修改我們應(yīng)用程序的日志級別。
- /metrics 詳細說明我們應(yīng)用程序的指標。這可能包括通用指標和自定義指標。
- /prometheus 返回與前面一樣的指標,但格式化為與Prometheus服務(wù)器一起工作。
- /scheduledtasks 提供了關(guān)于我們應(yīng)用程序中每個計劃任務(wù)的細節(jié)。
- /sessions 列出HTTP會話,因為我們使用的是Spring Session。
- /shutdown 執(zhí)行應(yīng)用程序的優(yōu)雅關(guān)閉。
- /threaddump 轉(zhuǎn)儲底層JVM的線程信息。
執(zhí)行器路徑的超媒體
Spring Boot
增加了一個所有路徑的集合入口,可以返回所有可用的執(zhí)行器路徑的鏈接。這將有助于發(fā)現(xiàn)執(zhí)行器路徑及其相應(yīng)的URL。默認情況下,這個集合入口可以通過 /actuator
路徑訪問。因此,如果我們向這個URL發(fā)送一個GET請求,它將返回各種路徑的執(zhí)行器鏈接。
{
"_links": {
"self": {
"href": "http://localhost:8080/actuator",
"templated": false
},
"features-arg0": {
"href": "http://localhost:8080/actuator/features/{arg0}",
"templated": true
},
"features": {
"href": "http://localhost:8080/actuator/features",
"templated": false
},
"beans": {
"href": "http://localhost:8080/actuator/beans",
"templated": false
},
"caches-cache": {
"href": "http://localhost:8080/actuator/caches/{cache}",
"templated": true
},
// ...
}
如上所示,/actuator
路徑在 _links
字段下報告所有可用的執(zhí)行器路徑。如果我們配置了一個自定義的管理基礎(chǔ)路徑,那么我們應(yīng)該能使用該集合入口發(fā)現(xiàn)URL。例如,如果我們將management.endpoints.web.base-path
設(shè)置為 /mgmt
,那么我們應(yīng)該向 /mgmt
路徑發(fā)送請求,以查看鏈接列表。但是如果當管理集合入口被設(shè)置為 / 時,集合入口被禁用,以防止與其他映射發(fā)生沖突的可能性。
健康指示器
就像以前的版本一樣,我們可以很容易地添加自定義指標。與其他 API 相反,用于創(chuàng)建自定義健康路徑的抽象概念保持不變。然而,一個新的接口,即 ReactiveHealthIndicator
,已經(jīng)被添加到實現(xiàn)反應(yīng)式健康檢查。讓我們來看看一個簡單的自定義反應(yīng)式健康檢查。
@Component
public class DownstreamServiceHealthIndicator implements ReactiveHealthIndicator {
@Override
public Mono< Health > health() {
return checkDownstreamServiceHealth().onErrorResume(
ex - > Mono.just(new Health.Builder().down(ex).build())
);
}
private Mono< Health > checkDownstreamServiceHealth() {
return Mono.just(new Health.Builder().up().build());
}
}
健康指標的一個方便的特點是,我們可以把它們作為一個層次結(jié)構(gòu)的一部分進行匯總。因此,按照前面的例子,我們可以把所有的下游服務(wù)歸入一個下游服務(wù)類別。只要每個嵌套的服務(wù)都是可以到達的,這個類別就會是健康的。
健康組
從 Spring Boot 2.2
開始,我們可以將健康指標組織成組,并對所有組員應(yīng)用相同的配置。例如,我們可以通過在 application.properties
中添加以下內(nèi)容來創(chuàng)建一個名為 custom
的健康組。
management.endpoint.health.group.custom.include=diskSpace,ping
這樣,自定義組包含 diskSpace
和 ping
健康指標。現(xiàn)在,如果我們調(diào)用 /actuator/health
路徑,它將在 JSON
響應(yīng)中告訴我們關(guān)于新的健康組。
{"status":"UP","groups":["custom"]}
通過健康組,我們可以看到一些健康指標的匯總結(jié)果。在這種情況下,如果我們向 /actuator/health/custom
發(fā)送一個請求,
{"status": "UP"}
我們可以通過 application.properties
來配置該組,以顯示更多細節(jié)。
management.endpoint.health.group.custom.show-components=always
management.endpoint.health.group.custom.show-details=always
現(xiàn)在,如果我們向 /actuator/health/custom
發(fā)送同樣的請求,我們會看到更多的細節(jié)。
{
"status": "UP",
"components": {
"diskSpace": {
"status": "UP",
"details": {
"total": 499963170816,
"free": 91300069376,
"threshold": 10485760
}
},
"ping": {
"status": "UP"
}
}
}
也可以只為授權(quán)用戶顯示這些細節(jié)。
management.endpoint.health.group.custom.show-components=when_authorized
management.endpoint.health.group.custom.show-details=when_authorized
我們還可以有一個自定義的狀態(tài)映射。例如,它可以不返回 HTTP 200 OK
響應(yīng),而是返回 207 狀態(tài)代碼。
management.endpoint.health.group.custom.status.http-mapping.up=207
在這里,我們要告訴 Spring Boot
,如果自定義組的狀態(tài)是 UP,就返回 207 的 HTTP 狀態(tài)代碼。
Spring Boot 2中的度量
在 Spring Boot 2.0
中,內(nèi)部指標被 Micrometer 支持所取代,因此我們可以預期會有一些變化。如果我們的應(yīng)用程序正在使用 GaugeService 或 CounterService 等度量衡服務(wù),它們將不再可用。
相反,我們要與 Micrometer 直接互動。在 Spring Boot 2.0
中,我們會得到一個自動配置的 MeterRegistry 類型的 bean。此外,Micrometer 現(xiàn)在是 Actuator 依賴的一部分,所以只要 Actuator 的依賴在 classpath 中,我們就應(yīng)該可以使用了。此外,我們將從 /metrics
端點得到一個全新的響應(yīng)。
{
"names": [
"jvm.gc.pause",
"jvm.buffer.memory.used",
"jvm.memory.used",
"jvm.buffer.count",
// ...
]
}
正如我們所看到的,沒有像我們在1.x中得到的實際度量。為了得到一個特定指標的實際值,我們現(xiàn)在可以導航到所需的指標,例如,/actuator/metrics/jvm.gc.pause
,然后得到一個詳細的響應(yīng)。
{
"name": "jvm.gc.pause",
"measurements": [
{
"statistic": "Count",
"value": 3.0
},
{
"statistic": "TotalTime",
"value": 7.9E7
},
{
"statistic": "Max",
"value": 7.9E7
}
],
"availableTags": [
{
"tag": "cause",
"values": [
"Metadata GC Threshold",
"Allocation Failure"
]
},
{
"tag": "action",
"values": [
"end of minor GC",
"end of major GC"
]
}
]
}
現(xiàn)在的度量標準要徹底得多,不僅包括不同的值,還包括一些相關(guān)的元數(shù)據(jù)。
創(chuàng)建一個自定義路徑
正如我們之前指出的,我們可以創(chuàng)建自定義路徑。不過,Spring Boot 2重新設(shè)計了實現(xiàn)的方式,以支持新的技術(shù)無關(guān)的范式。讓我們創(chuàng)建一個Actuator路徑,在我們的應(yīng)用程序中查詢、啟用和禁用功能標志。
@Component
@Endpoint(id = "features")
public class FeaturesEndpoint {
private Map< String, Feature > features = new ConcurrentHashMap< >();
@ReadOperation
public Map< String, Feature > features() {
return features;
}
@ReadOperation
public Feature feature(@Selector String name) {
return features.get(name);
}
@WriteOperation
public void configureFeature(@Selector String name, Feature feature) {
features.put(name, feature);
}
@DeleteOperation
public void deleteFeature(@Selector String name) {
features.remove(name);
}
public static class Feature {
private Boolean enabled;
// [...] getters and setters
}
}
為了獲得路徑,我們需要一個Bean。在我們的例子中,我們使用@Component來做這個。同時,我們需要用@Endpoint來裝飾這個Bean。我們的端點的路徑是由@Endpoint的id參數(shù)決定的。在我們的例子中,它將把請求路由到/actuator/features。一旦準備就緒,我們就可以開始使用定義操作了。
- @ReadOperation。它將映射到HTTP GET。
- @WriteOperation。它將映射到HTTP POST。
- @DeleteOperation。它將映射到HTTP DELETE。
當我們在應(yīng)用程序中使用前一個端點運行應(yīng)用程序時,Spring Boot將注冊它。驗證這一點的一個快速方法是檢查日志。
擴展現(xiàn)有的端點
想象一下,如果我們想確保應(yīng)用程序的生產(chǎn)實例永遠不是SNAPSHOT版本。我們決定通過改變返回該信息的 Actuator 端點的HTTP狀態(tài)代碼,即/info來做到這一點。如果我們的應(yīng)用程序碰巧是SNAPSHOT,我們會得到一個不同的HTTP狀態(tài)代碼。
我們可以使用 @EndpointExtension 注解,或其更具體的特殊化@EndpointWebExtension或@EndpointJmxExtension,輕松地擴展預定義端點的行為。
@Component
@EndpointWebExtension(endpoint = InfoEndpoint.class)
public class InfoWebEndpointExtension {
private InfoEndpoint delegate;
@ReadOperation
public WebEndpointResponse< Map > info() {
Map< String, Object > info = this.delegate.info();
Integer status = getStatus(info);
return new WebEndpointResponse< >(info, status);
}
private Integer getStatus(Map< String, Object > info) {
return 200;
}
}
啟用所有端點
為了能夠使用 HTTP 訪問 Actuator 的端點,我們需要啟用和公開它們。默認情況下,除了/shutdown,所有的端點都是啟用的。默認情況下,只有/health和/info這兩個端點是公開的。我們需要添加以下配置來公開所有端點。
management.endpoints.web.exposure.include=*
要明確地啟用一個特定的端點(例如,/shutdown)
management.endpoint.shutdown.enabled=true
要公開所有已啟用的端點,除了一個(例如,/loggers)
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=loggers
總結(jié)
在這篇文章中,我們談到了Spring Boot Actuator。我們首先解釋了Actuator的含義以及它為我們做了什么。接下來,我們重點討論了當前Spring Boot 2.x版本的Actuator,討論了如何使用它、調(diào)整它和擴展它。我們還談到了在這個新的迭代中我們可以發(fā)現(xiàn)的重要的安全變化。我們討論了一些流行的端點,以及它們是如何變化的。
-
代碼
+關(guān)注
關(guān)注
30文章
4807瀏覽量
68786 -
應(yīng)用程序
+關(guān)注
關(guān)注
37文章
3284瀏覽量
57773 -
軟件包
+關(guān)注
關(guān)注
0文章
104瀏覽量
11617 -
SpringBoot
+關(guān)注
關(guān)注
0文章
174瀏覽量
186
發(fā)布評論請先 登錄
相關(guān)推薦
評論