去年咱們項目作了微服務1.0的架構轉型,可是服務監控這塊卻沒有跟上。這不,最近我就被分配了要將咱們核心的微服務應用所有監控起來的任務。咱們的微服務應用都是SpringBoot 應用,所以就天然而然的想到了藉助Spring Boot 的Actuator 模塊。(沒吃過豬肉總聽過豬叫見過豬跑吧🤪)。html
本篇是我在完成這個工單以後,對Spring Boot Actuator模塊 學習應用的總結。在本篇文章中,你能夠學習到:java
以後我還會介紹:git
Spring Boot Actuator 模塊提供了生產級別的功能,好比健康檢查,審計,指標收集,HTTP 跟蹤等,幫助咱們監控和管理Spring Boot 應用。這個模塊是一個採集應用內部信息暴露給外部的模塊,上述的功能均可以經過HTTP 和 JMX 訪問。github
由於暴露內部信息的特性,Actuator 也能夠和一些外部的應用監控系統整合(Prometheus, Graphite, DataDog, Influx, Wavefront, New Relic等)。這些監控系統提供了出色的儀表板,圖形,分析和警報,可幫助你經過一個統一友好的界面,監視和管理你的應用程序。web
Actuator使用Micrometer與這些外部應用程序監視系統集成。這樣一來,只需不多的配置便可輕鬆集成外部的監控系統。redis
Micrometer 爲 Java 平臺上的性能數據收集提供了一個通用的 API,應用程序只須要使用 Micrometer 的通用 API 來收集性能指標便可。Micrometer 會負責完成與不一樣監控系統的適配工做。這就使得切換監控系統變得很容易。對比 Slf4j 之於 Java Logger 中的定位。spring
咱們先建立一個demo應用。chrome
spring init -d=web,actuator -n=actuator-demo actuator-demo
<dependencies> ... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> ... </dependencies>
dependencies { compile("org.springframework.boot:spring-boot-starter-actuator") }
Spring Boot 提供了所謂的 endpoints (下文翻譯爲端點)給外部來與應用程序進行訪問和交互。shell
打比方來講,/health
端點 提供了關於應用健康狀況的一些基礎信息。metrics
端點提供了一些有用的應用程序指標(JVM 內存使用、系統CPU使用等)。數據庫
這些 Actuator 模塊原本就有的端點咱們稱之爲原生端點。根據端點的做用的話,咱們大概能夠分爲三大類:
詳細的原生端點介紹,請以 官網爲準,這裏就不贅述徒增篇幅。
須要注意的就是:
/actuator
前綴。默認暴露的兩個端點爲/actuator/health
和 /actuator/info
咱們能夠經過如下配置,來配置經過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 |
能夠打開全部的監控點
management.endpoints.web.exposure.include=*
也能夠選擇打開部分,"*" 表明暴露全部的端點,若是指定多個端點,用","分開
management.endpoints.web.exposure.exclude=beans,trace
Actuator 默認全部的監控點路徑都在/actuator/*
,固然若是有須要這個路徑也支持定製。
management.endpoints.web.base-path=/minitor
設置完重啓後,再次訪問地址就會變成/minitor/*
。
如今咱們按照以下配置:
# "*" 表明暴露全部的端點 若是指定多個端點,用","分開 management.endpoints.web.exposure.include=* # 賦值規則同上 management.endpoints.web.exposure.exclude=
啓動DEMO程序,訪問http://localhost:8080/actuator
,查看暴露出來的端點:
上面這樣顯示是由於chrome 瀏覽器安裝了 JSON-handle 插件,實際上就是返回一大段json
下面,我會着重介紹幾個比較重要的端點。
/health
端點/health
端點會聚合你程序的健康指標,來檢查程序的健康狀況。端點公開的應用健康信息取決於:
management.endpoint.health.show-details=always
該屬性可使用如下值之一進行配置:
Name | Description |
---|---|
never |
不展現詳細信息,up或者down的狀態,默認配置 |
when-authorized |
詳細信息將會展現給經過認證的用戶。受權的角色能夠經過management.endpoint.health.roles 配置 |
always |
對全部用戶暴露詳細信息 |
按照上述配置,配置成always
以後,咱們啓動項目,訪問http://localhost:8080/actuator/health
端口,能夠看到這樣的信息:
是否是感受好像健康信息有點少?先別急,那是由於咱們建立的是一個最基礎的Demo項目,沒有依賴不少的組件。
/health
端點有不少自動配置的健康指示器:如redis、rabbitmq、db等組件。當你的項目有依賴對應組件的時候,這些健康指示器就會被自動裝配,繼而採集對應的信息。如上面的 diskSpace 節點信息就是DiskSpaceHealthIndicator
在起做用。
上述截圖取自 官方文檔
這是我另外一個項目的/health
端點信息。
當如上的組件有一個狀態異常,應用服務的總體狀態即爲down。咱們也能夠經過配置禁用某個組件的健康監測。
management.health.mongo.enabled: false
或者禁用全部自動配置的健康指示器:
management.health.defaults.enabled: false
固然你也能夠自定義一個Health Indicator,只須要實現HealthIndicator
接口或者繼承AbstractHealthIndicator
類。
/** * @author Richard_yyf * @version 1.0 2020/1/16 */ @Component public class CustomHealthIndicator extends AbstractHealthIndicator { @Override protected void doHealthCheck(Health.Builder builder) throws Exception { // 使用 builder 來建立健康狀態信息 // 若是你throw 了一個 exception,那麼status 就會被置爲DOWN,異常信息會被記錄下來 builder.up() .withDetail("app", "這個項目很健康") .withDetail("error", "Nothing, I'm very good"); } }
最終效果:
/metrics
端點/metrics
端點用來返回當前應用的各種重要度量指標,好比:內存信息、線程信息、垃圾回收信息、tomcat、數據庫鏈接池等。
{ "names": [ "tomcat.threads.busy", "jvm.threads.states", "jdbc.connections.active", "jvm.gc.memory.promoted", "http.server.requests", "hikaricp.connections.max", "hikaricp.connections.min", "jvm.memory.used", "jvm.gc.max.data.size", "jdbc.connections.max", .... ] }
不一樣於1.x,Actuator在這個界面看不到具體的指標信息,只是展現了一個指標列表。爲了獲取到某個指標的詳細信息,咱們能夠請求具體的指標信息,像這樣:
http://localhost:8080/actuator/metrics/{MetricName}
好比我訪問/actuator/metrics/jvm.memory.max
,返回信息以下:
你也能夠用query param的方式查看單獨的一塊區域。好比你能夠訪問/actuator/metrics/jvm.memory.max?tag=id:Metaspace
。結果就是:
/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
端點能夠用來展現你程序的信息。我理解過來就是一些程序的基礎信息。而且你能夠按照本身的需求在配置文件application.properties
中個性化配置(默認狀況下,該端點只會返回一個空的json內容。):
info.app.name=actuator-test-demo info.app.encoding=UTF-8 info.app.java.source=1.8 info.app.java.target=1.8 # 在 maven 項目中你能夠直接用下列方式引用 maven properties的值 # info.app.encoding=@project.build.sourceEncoding@ # info.app.java.source=@java.version@ # info.app.java.target=@java.version@
啓動項目,訪問http://localhost:8080/actuator/info
:
{ "app": { "encoding": "UTF-8", "java": { "source": "1.8.0_131", "target": "1.8.0_131" }, "name": "actuator-test-demo" } }
/beans
端點/beans
端點會返回Spring 容器中全部bean的別名、類型、是否單例、依賴等信息。
訪問http://localhost:8080/actuator/beans
,返回以下:
/heapdump
端點訪問:http://localhost:8080/actuator/heapdump
會自動生成一個 Jvm 的堆文件 heapdump。咱們可使用 JDK 自帶的 Jvm 監控工具 VisualVM 打開此文件查看內存快照。
/threaddump
端點這個端點我我的以爲特別有用,方便咱們在平常定位問題的時候查看線程的狀況。 主要展現了線程名、線程ID、線程的狀態、是否等待鎖資源、線程堆棧等信息。就是可能查看起來不太直觀。訪問http://localhost:8080/actuator/threaddump
返回以下:
/shutdown
端點這個端點屬於操做控制類端點,能夠優雅關閉 Spring Boot 應用。要使用這個功能首先須要在配置文件中開啓:
management.endpoint.shutdown.enabled=true
因爲 shutdown 接口默認只支持 POST 請求,咱們啓動Demo項目,向http://localhost:8080/actuator/shutdown
發起POST
請求。返回信息:
{ "message": "Shutting down, bye..." }
而後應用程序被關閉。
因爲開放關閉應用的操做自己是一件很是危險的事,因此真正在線上使用的時候,咱們須要對其加入必定的保護機制,好比:定製Actuator的端點路徑、整合Spring Security進行安全校驗等。(不是特別必要的話,這個端點不用開)
因爲端點的信息和產生的交互都是很是敏感的,必須防止未經受權的外部訪問。若是您的應用程序中存在Spring Security的依賴,則默認狀況下使用基於表單的HTTP身份驗證來保護端點。
若是沒有,只須要增長對應的依賴便可:
<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; /** * @author Richard_yyf */ @Configuration public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter { /* * version1: * 1. 限制 '/shutdown'端點的訪問,只容許ACTUATOR_ADMIN訪問 * 2. 容許外部訪問其餘的端點 * 3. 容許外部訪問靜態資源 * 4. 容許外部訪問 '/' * 5. 其餘的訪問須要被校驗 * version2: * 1. 限制全部端點的訪問,只容許ACTUATOR_ADMIN訪問 * 2. 容許外部訪問靜態資源 * 3. 容許外部訪問 '/' * 4. 其餘的訪問須要被校驗 */ @Override protected void configure(HttpSecurity http) throws Exception { // version1 // 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(); // version2 http .authorizeRequests() .requestMatchers(EndpointRequest.toAnyEndpoint()) .hasRole("ACTUATOR_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=ACTUATOR_ADMIN
本篇文章內容就到這裏。
對應的源碼能夠Github上看到。
若是本文有幫助到你,但願能點個贊,這是對個人最大動力🤝🤝🤗🤗。