《Spring Boot Actuator詳解與深入應用》預計包括三篇,第一篇重點講Spring Boot Actuator 1.x的應用與定製端點;第二篇將會對比Spring Boot Actuator 2.x 與1.x的區別,以及應用和定製2.x的端點;第三篇將會介紹Actuator metric指標與Prometheus和Grafana的使用結合。這部分內容很常用,且較爲入門,歡迎大家的關注。
Actuator是什麼
Spring Boot Actuator提供了生產上經常用到的功能(如健康檢查,審計,指標收集,HTTP跟蹤等),幫助我們監控和管理Spring Boot應用程序。這些功能都可以通過JMX或HTTP端點訪問。
通過引入相關的依賴,即可監控我們的應用程序,收集指標、瞭解流量或數據庫的狀態變得很簡單。該庫的主要好處是我們可以獲得生產級工具,而無需自己實際實現這些功能。與大多數Spring模塊一樣,我們可以通過多種方式輕鬆配置或擴展它。
Actuator還可以與外部應用監控系統集成,如Prometheus,Graphite,DataDog,Influx,Wavefront,New Relic等等。 這些系統爲您提供出色的儀表板,圖形,分析和警報,以幫助我們在一個統一界面監控和管理應用服務。
本文將會介紹Spring Boot Actuator 1.x 包括其中的端點(HTTP端點)、配置管理以及擴展和自定義端點。
快速開始
引入如下的依賴:
1 <dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-actuator</artifactId> 4 </dependency>
Spring Boot Actuator 1.x
在1.x中,Actuator遵循讀寫模型,這意味着我們可以從中讀取信息或寫入信息。我們可以檢索指標或我們的應用程序的健康狀況,當然我們也可以優雅地終止我們的應用程序或更改我們的日誌配置。Actuator通過Spring MVC暴露其HTTP端點。
端點
當引入的Actuator的版本爲1.x時,啓動應用服務,可以控制檯輸出如下的端點信息:
我們介紹一下常用的endpoints:
- /health:顯示應用程序運行狀況信息(通過未經身份驗證的連接訪問時的簡單“狀態”或經過身份驗證時的完整消息詳細信息),它默認不敏感
- /info:顯示應用程序信息,默認情況下不敏感
- /metrics:顯示當前應用程序的“指標”信息,它默認也很敏感
- /trace:顯示跟蹤信息(默認情況下是最後幾個HTTP請求)
有些端點默認並不會被開啓,如/shutdown。
配置端點
我們可以自定義每個端點的屬性,按照如下的格式:
1endpoints.[endpoint name].[property to customize]
可以自定義的屬性有如下三個:
- id,暴露的http端點地址
- enabled,是否開啓
- sensitive,當爲true時,需要認證之後纔會通過http獲取到敏感信息
我們在配置文件中增加如下的配置,將會定製/beans端點。
1endpoints.beans.id=springbeans 2endpoints.beans.sensitive=false 3endpoints.beans.enabled=true
/health端點
/health端點用於監控運行的服務實例狀態,當服務實例下線或者因爲其他的原因變得異常(如DB連接不上,磁盤缺少空間)時,將會及時通知運維人員。
在默認未授權的情況下,通過HTTP的方式僅會返回如下的簡單信息:
1{ 2 "status": "UP" 3}
獲取詳細的health信息
我們進行如下的配置:
1endpoints: 2 health: 3 id: chealth 4 sensitive: false 5 6management.security.enabled: false
如上一小節所述,我們更改了/health端點的訪問路徑爲/chealth,並將安全授權關閉。訪問http://localhost:8005/chealth
將會得到如下的結果。
1{ 2 "status": "UP", 3 "healthCheck": { 4 "status": "UP" 5 }, 6 "diskSpace": { 7 "status": "UP", 8 "total": 999995129856, 9 "free": 762513104896, 10 "threshold": 10485760 11 } 12}
自定義health的信息
我們還可以定製實現health指示器。它可以收集特定於應用程序的任何類型的自定義運行狀況數據,並通過/health端點訪問到定義的信息。
1@Component 2public class HealthCheck implements HealthIndicator { 3 4 @Override 5 public Health health() { 6 int errorCode = check(); // perform some specific health check 7 if (errorCode != 0) { 8 return Health.down() 9 .withDetail("Error Code", errorCode).build(); 10 } 11 return Health.up().build(); 12 } 13 14 public int check() { 15 // Our logic to check health 16 return 0; 17 } 18}
實現HealthIndicator
接口,並覆寫其中的health()
方法即可自定義我們的/health端點。
/info端點
通過/info端點,我們可以爲應用服務定義一些基本信息:
1info.app.name=Spring Sample Application 2info.app.description=This is my first spring boot application 3info.app.version=1.0.0
我們在如上的配置中定義了服務名、描述和服務的版本號。
/metrics端點
/metrics端點展示了OS、JVM和應用級別的指標信息。當開啓之後,我們可以獲取內存、堆、線程、線程池、類加載和HTTP等信息。
1{ 2 "mem": 417304, 3 "mem.free": 231678, 4 "processors": 4, 5 "instance.uptime": 248325, 6 "uptime": 250921, 7 "systemload.average": 1.9541015625, 8 "heap.committed": 375296, 9 "heap.init": 393216, 10 "heap.used": 143617, 11 "heap": 5592576, 12 "nonheap.committed": 43104, 13 "nonheap.init": 2496, 14 "nonheap.used": 42010, 15 "nonheap": 0, 16 "threads.peak": 30, 17 "threads.daemon": 18, 18 "threads.totalStarted": 46, 19 "threads": 20, 20 "classes": 6020, 21 "classes.loaded": 6020, 22 "classes.unloaded": 0, 23 "gc.ps_scavenge.count": 3, 24 "gc.ps_scavenge.time": 35, 25 "gc.ps_marksweep.count": 1, 26 "gc.ps_marksweep.time": 29, 27 "httpsessions.max": -1, 28 "httpsessions.active": 0, 29 "gauge.response.info": 38.0, 30 "counter.status.200.info": 1 31}
定製metrics端點
爲了收集自定義的metrics,Actuator支持單數值記錄的功能,簡單的增加/減少計數功能。如下的實現,我們將登錄成功和失敗的次數作爲自定義指標記錄下來。
1@Service 2public class LoginServiceImpl implements LoginService { 3 private final CounterService counterService; 4 5 @Autowired 6 public LoginServiceImpl(CounterService counterService) { 7 this.counterService = counterService; 8 } 9 10 @Override 11 public Boolean login(String userName, char[] password) { 12 boolean success; 13 if (userName.equals("admin") && "secret".toCharArray().equals(password)) { 14 counterService.increment("counter.login.success"); 15 success = true; 16 } else { 17 counterService.increment("counter.login.failure"); 18 success = false; 19 } 20 return success; 21 } 22}
再次訪問/metrics,發現多瞭如下的指標信息。登錄嘗試和其他安全相關事件在Actuator中可用作審計事件。
1{ 2 "gauge.response.metrics": 2.0, 3 "gauge.response.test": 3.0, 4 "gauge.response.star-star.favicon.ico": 1.0, 5 "counter.status.200.star-star.favicon.ico": 10, 6 "counter.status.200.test": 6, 7 "counter.login.failure": 6, 8 "counter.status.200.metrics": 4 9}
自定義端點
除了使用Spring Boot Actuator提供的端點,我們也可以定義一個全新的端點。
首先,我們需要實現Endpoint
接口:
1@Component 2public class CustomEndpoint implements Endpoint<List<String>> { 3 @Override 4 public String getId() { 5 return "custom"; 6 } 7 8 @Override 9 public boolean isEnabled() { 10 return true; 11 } 12 13 @Override 14 public boolean isSensitive() { 15 return false; 16 } 17 18 @Override 19 public List<String> invoke() { 20 // Custom logic to build the output 21 List<String> messages = new ArrayList<String>(); 22 messages.add("This is message 1"); 23 messages.add("This is message 2"); 24 return messages; 25 } 26}
getId()
方法用於匹配訪問這個端點,當我們訪問/custom時,將會調用invoke()
我們自定義的邏輯。
另外兩個方法,用於設置是否開啓和是否爲敏感的端點。
1[ "This is message 1", "This is message 2" ]
進一步定製
出於安全考慮,我們可能選擇通過非標準端口暴露Actuator端點。通過management.port屬性來配置它。
另外,正如我們已經提到的那樣,在1.x. Actuator基於Spring Security配置自己的安全模型,但獨立於應用程序的其餘部分。
因此,我們可以更改management.address屬性以限制可以通過網絡訪問端點的位置:
1#port used to expose actuator 2management.port=8081 3 4#CIDR allowed to hit actuator 5management.address=127.0.0.1
此外,除了/info端點,其他所有的端點默認都是敏感的,如果引入了Spring Security,我們通過在配置文件中定義這些安全的屬性(username, password, role)來確保內置端點的安全。
總結
Spring Boot Actuator爲我們的應用服務在生產環境提供了很多開箱即用的功能。本文主要講解了Spring Boot Actuator 1.x的深入使用。我們既可以使用內置的端點(如/health,/info等),可以在這些端點的基礎進行擴展和定製,還可以自定義全新的端點,在使用方式上顯得非常靈活。
參考
- Actuator docs :https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html
- Spring Boot Actuator: https://www.baeldung.com/spring-boot-actuators#boot-1x-actuator