微服務的特點決定了功能子產品的部署是分布式的,大部分功能子產品都是運作在不同的機器上,彼此通過服務調用進行互動,前背景的業務流會經過很多個微服務的處理和傳遞,出現了異常如何快速定位是哪個環節出現了問題?
在這種架構下,微服務的監控顯得尤為重要。本文主要結合Spring Boot Actuator,跟大家一起分享微服務Spring Boot Actuator的常見用法,友善我們在日常中對我們的微服務進行監控治理。
spring-boot-actuator子產品提供了一個監控和管理生産環境的子產品,可以使用http、jmx、ssh、telnet等來管理和監控應用。審計(Auditing)、 健康(health)、資料采集(metrics gathering)會自動加入到應用裡面。
1、添加依賴
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
為了保證actuator暴露的監控接口的安全性,需要添加安全控制的依賴spring-boot-start-security依賴,通路應用監控端點時,都需要輸入驗證資訊。Security依賴,可以選擇不加,不進行安全管理,但不建議這麼做。
2、application.yml配置檔案
server:
port: 8080
management:
security:
enabled: false #關掉安全認證
port: 8088 #管理端口調整成8088
context-path: /monitor #actuator的通路路徑
endpoints:
shutdown:
enabled: true
info:
app:
name: spring-boot-actuator
version: 1.0.0
management.security.enabled=false預設有一部分資訊需要安全驗證之後才可以檢視,如果去掉這些安全認證,直接設定management.security.enabled=false
management.context-path=/monitor 代表啟用單獨的url位址來監控Spring Boot應用,為了安全一般都啟用獨立的端口來通路後端的監控資訊
endpoints.shutdown.enabled=true 啟用接口關閉Spring Boot
配置完成之後,啟動項目就可以繼續驗證各個監控功能了。
服務通路URL:http://localhost:8080
監控通路URL:http://localhost:8088/monitor/

3、指令詳解
3.1、autoconfig
Spring Boot的自動配置功能非常便利,但有時候也意味着出問題比較難找出具體的原因。使用 autoconfig 可以在應用運作時檢視代碼某個配置在什麼條件下生效,或者某個自動配置為什麼沒有生效。
啟動示例項目,通路:http://localhost:8088/monitor/autoconfig
3.2、configprops
檢視配置檔案中設定的屬性内容,以及一些配置屬性的預設值。
啟動示例項目,通路:http://localhost:8088/monitor/configprops
3.3、beans
根據示例就可以看出,展示了bean的别名、類型、是否單例、類的位址、依賴等資訊。
啟動示例項目,通路:http://localhost:8088/monitor/beans
3.4、dump
/dump 接口會生成目前線程活動的快照。這個功能非常好,友善我們在日常定位問題的時候檢視線程的情況。
主要展示了線程名、線程ID、線程的狀态、是否等待鎖資源等資訊。
啟動示例項目,通路:http://localhost:8088/monitor/dump
3.5、env
展示了系統環境變量的配置資訊,包括使用的環境變量、JVM 屬性、指令行參數、項目使用的jar包等資訊。和configprops不同的是,configprops關注于配置資訊,env關注運作環境資訊。
啟動示例項目,通路:http://localhost:8088/monitor/env
為了避免敏感資訊暴露到 /env 裡,所有名為password、secret、key(或者名字中最後一段是這些)的屬性在 /env 裡都會加上“*”。
舉個例子,如果有一個屬性名字是database.password,那麼它在/env中的顯示效果是這樣的:"database.password":"******"
/env/{name}用法
就是env的擴充 可以擷取指定配置資訊,比如:http://localhost:8088/monitor/env/java.vm.version,傳回:{"java.vm.version":"25.101-b13"}
3.6、health
可以看到 HealthEndPoint 給我們提供預設的監控結果,包含磁盤檢測和資料庫檢測
啟動示例項目,通路:http://localhost:8088/monitor/health傳回部分資訊,下面的JSON響應是由狀态、磁盤空間和db。描述了應用程式的整體健康狀态,UP 表明應用程式是健康的。磁盤空間描述總磁盤空間,剩餘的磁盤空間和最小門檻值。application.properties門檻值是可配置的
{
"status": "UP",
"diskSpace": {
"status": "UP",
"total": 209715195904,
"free": 183253909504,
"threshold": 10485760
}
"db": {
"status": "UP",
"database": "MySQL",
"hello": 1
}
}
其實看 Spring Boot-actuator 源碼,你會發現 HealthEndPoint 提供的資訊不僅限于此,org.springframework.boot.actuate.health 包下 你會發現 ElasticsearchHealthIndicator、RedisHealthIndicator、RabbitHealthIndicator 等
3.7、info
info就是我們自己配置在配置檔案中以Info開頭的配置資訊,比如我們在示例項目中的配置是:
info:
app:
name: spring-boot-actuator
version: 1.0.0
啟動示例項目,通路:http://localhost:8088/monitor/info傳回部分資訊如下:
{
"app": {
"name": "spring-boot-actuator",
"version": "1.0.0"
}
}
3.8、mappings
描述全部的URI路徑,以及它們和控制器的映射關系
啟動示例項目,通路:http://localhost:8088/monitor/mappings
3.9、metrics
最重要的監控内容之一,主要監控了JVM内容使用、GC情況、類加載資訊等。
啟動示例項目,通路:http://localhost:8088/monitor/metrics
{
"mem": 364438, #系統記憶體總量,機關:Kb
"mem.free": 251876, #空閑記憶體數量,機關:Kb
"processors": 8, #處理器數量
"instance.uptime": 12758821, #應用上下文(就是一個應用執行個體)正常運作時間,機關:毫秒
"uptime": 12761352, #系統正常運作時間,機關:毫秒
"systemload.average": -1.0, #系統平均負載
"heap.committed": 310272, #堆資訊
"heap.init": 131072, #堆資訊
"heap.used": 58395, #堆資訊
"heap": 1840640, #堆資訊
"nonheap.committed": 56704, #
"nonheap.init": 2496, #
"nonheap.used": 54167, #
"nonheap": 0, #
"threads.peak": 47, #線程資訊
"threads.daemon": 38, #線程資訊
"threads.totalStarted": 51, #線程資訊
"threads": 41, #線程資訊
"classes": 6635, #類加載資訊
"classes.loaded": 6677, #類加載資訊
"classes.unloaded": 42, #類加載資訊
"gc.ps_scavenge.count": 7, #垃圾收集資訊
"gc.ps_scavenge.time": 75, #垃圾收集資訊
"gc.ps_marksweep.count": 2, #垃圾收集資訊
"gc.ps_marksweep.time": 122, #垃圾收集資訊
"httpsessions.max": -1, #
"httpsessions.active": 0, #
"gauge.response.hello": 2.0, #
"gauge.response.star-star.favicon.ico": 2.0, #
"counter.status.200.star-star.favicon.ico": 5, #
"counter.status.200.hello": 7 #
}
對 /metrics 接口提供的資訊進行簡單分類如下表:
解釋說明:
請注意,這裡的一些路徑成本,比如資料源和Tomcat會話,僅在應用程式中運作特定元件時才有資料。你還可以注冊自己的度量資訊。
HTTP的計數器和路徑成本需要做一點說明。counter.status 後的值是HTTP狀态碼,随後是所請求的路徑。舉個例子,counter.status.200.metrics 表明/metrics端點傳回 200(OK) 狀态碼的次數。
HTTP的度量資訊在結構上也差不多,卻在報告另一類資訊。它們全部以gauge.response 開頭,,表明這是HTTP響應的度量資訊。字首後是對應的路徑。路徑成本是以毫秒為機關的時間,反映了最近處理該路徑請求的耗時。
這裡還有幾個特殊的值需要注意。root路徑指向的是根路徑或/。star-star代表了那些Spring 認為是靜态資源的路徑,包括圖檔、JavaScript和樣式表,其中還包含了那些找不到的資源。這就是為什麼你經常會看到 counter.status.404.star-star,這是傳回了HTTP 404 (NOT FOUND) 狀态的請求數。
/metrics接口會傳回所有的可用路徑成本,但你也可能隻對某個值感興趣。要擷取單個值,請求時可以在URL後加上對應的鍵名。例如,要檢視空閑記憶體大小,可以向/metrics/mem.free發一 個GET請求。例如通路:http://localhost:8088/monitor/metrics/mem.free,傳回:{"mem.free":178123}。
還會為應用中定義的支援的DataSource提供以下名額:
最大連接配接數(datasource.xxx.max)
最小連接配接數(datasource.xxx.min)
活動連接配接數(datasource.xxx.active)
連接配接池的使用情況(.xxx.usage)
所有的資料源名額共用 datasoure. 字首。該字首對每個資料源都非常合适:
1、如果是主資料源(唯一可用的資料源或存在的資料源中被@Primary标記的)字首為datasource.primary。
2、如果資料源bean名稱以dataSource結尾,那字首就是bean的名稱去掉dataSource的部分(例如,batchDataSource的字首是datasource.batch)
3、其他情況使用bean的名稱作為字首
4.0、shutdown
開啟接口優雅關閉Spring Boot應用,要使用這個功能首先需要在配置檔案中開啟:
endpoints:
shutdown:
enabled: true
配置完成之後,啟動示例項目,通路:http://localhost:8088/monitor/shutdown傳回部分資訊如下:
{
"message": "Shutting down, bye..."
}
此時你會發現應用已經被關閉。
4.1、trace
/trace接口能報告所有Web請求的詳細資訊,包括請求方法、路徑、時間戳以及請求和響應的頭資訊,記錄每一次請求的詳細資訊。
啟動示例項目,先通路一次:http://localhost:8080/hello,再到浏覽器執行:http://localhost:8088/monitor/trace檢視傳回資訊:
[
{
"timestamp": 1516780334777,
"info": {
"method": "GET",
"path": "/hello",
"headers": {
"request": {
"host": "localhost:8080",
"connection": "keep-alive",
"cache-control": "max-age=0",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
"upgrade-insecure-requests": "1",
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"accept-encoding": "gzip, deflate, br",
"accept-language": "zh-CN,zh;q=0.9",
"cookie": "UM_distinctid=16053ba344f1cd-0dc220c44cc94-b7a103e-13c680-16053ba3450751; Hm_lvt_0fb30c642c5f6453f17d881f529a1141=1513076406,1514961720,1515649377; CNZZDATA1260945749=232252692-1513233181-%7C1516085149; Hm_lvt_6d8e8bb59814010152d98507a18ad229=1515247964,1515296008,1515672972,1516086283"
},
"response": {
"X-Application-Context": "application:8080",
"Content-Type": "text/html;charset=UTF-8",
"Content-Length": "11",
"Date": "Wed, 24 Jan 2018 07:52:14 GMT",
"status": "200"
}
},
"timeTaken": "4"
}
}
]
上述資訊展示了,/hello請求的詳細資訊。
4、其它配置
a、敏感資訊通路限制
根據上面表格,鑒權為false的,表示不敏感,可以随意通路,否則就是做了一些保護,不能随意通路。
endpoints.mappings.sensitive=false
這樣需要對每一個都設定,比較麻煩。敏感方法預設是需要使用者擁有ACTUATOR角色,是以,也可以設定關閉安全限制:
management.security.enabled=false
或者配合Spring Security做細粒度控制。