Actuator 監控
<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>
</dependencies>
Actuator 的 REST 接⼝
- 應⽤配置類,可以查看應⽤在運⾏期的靜態信息,例如⾃動配置信息、加載的 springbean 信息、yml ⽂ 件配置信息、環境信息、請求映射信息;
- 度量指標類,主要是運⾏期的動態信息,如堆棧、請求連、⼀些健康指標、metrics 信息等;
- 操作控制類,主要是指 shutdown,⽤戶可以發送⼀個請求將應⽤的監控功能關閉。
HTTP ⽅方法 |
路路徑 |
描述 |
GET |
/auditevents |
顯示應⽤用暴暴露露的審計事件(如認證進⼊入、訂單失敗) |
GET |
/beans |
描述應⽤用程序上下⽂文⾥裏里全部的 Bean 以及它們的關係 |
GET |
/conditions |
就是 1.0 的 /autoconfig,提供⼀一份⾃自動配置⽣生效的條件情況,記錄哪些 ⾃自動配置條件通過了了,哪些沒通過 |
GET |
/configprops |
描述配置屬性(包含默認值)如何注⼊入 Bean |
GET |
/env |
獲取全部環境屬性 |
GET |
/env/{name} |
根據名稱獲取特定的環境屬性值 |
GET |
/flyway |
提供⼀一份 Flyway 數據庫遷移信息 |
GET |
/liquidbase |
顯示 Liquibase 數據庫遷移的纖細信息 |
GET |
/health |
報告應⽤用程序的健康指標,這些值由 HealthIndicator 的實現類提供 |
GET |
/heapdump |
dump ⼀一份應⽤用的 JVM 堆信息 |
GET |
/httptrace |
顯示 HTTP ⾜足跡,最近 100 個 HTTP request/repsponse |
GET |
/info |
獲取應⽤用程序的定製信息,這些信息由 info 打頭的屬性提供 |
GET |
/logfile |
返回 log file 中的內容(如果 logging.file 或者 logging.path 被設置) |
GET |
/loggers |
顯示和修改配置的 loggers |
GET |
/metrics |
報告各種應⽤用程序度量量信息,⽐比如內存⽤用量量和 HTTP 請求計數 |
GET |
/metrics/{name} |
報告指定名稱的應⽤用程序度量量值 |
GET |
/scheduledtasks |
展示應⽤用中的定時任務信息 |
GET |
/sessions |
如果我們使⽤用了了 Spring Session 展示應⽤用中的 HTTP Sessions 信息 |
POST |
/shutdown |
關閉應⽤用程序,要求 endpoints.shutdown.enabled 設置爲 true |
GET |
/mappings |
描述全部的 URI 路路徑,以及它們和控制器器(包含 Actuator 端點)的映射關係 |
GET |
/threaddump |
獲取線程活動的快照 |
命令詳解
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=beans,trace
management.endpoints.web.base-path=/manage
health
{
"status" : "UP"
}
- 設置狀態碼順序爲 setStatusOrder(Status.DOWN, Status.OUTOFSERVICE, Status.UP, Status.UNKNOWN);
- 過濾掉不能識別的狀態碼
- 如果⽆任何狀態碼,整個 Spring Boot 應⽤的狀態是 UNKNOWN
- 將所有收集到的狀態碼按照 1 中的順序排序
- 返回有序狀態碼序列中的第⼀個狀態碼,作爲整個 Spring Boot 應⽤的狀態
management.health.redise.enabled=false
詳細的健康檢查信息
management.endpoint.health.show-details=always
"status": "UP",
"diskSpace": {
"status": "UP",
"total": 209715195904,
"free": 183253909504,
"threshold": 10485760
}
}
info
info 是我們⾃⼰在配置⽂件中以 info 開頭的配置信息,⽐如在示例項⽬中的配置是:
info.app.name=spring-boot-actuator
info.app.version= 1.0.0
info.app.test= test
啓動示例項⽬,訪問 http://localhost:8080/actuator/info 返回部分信息如下:
{
"app": {
"name": "spring-boot-actuator",
"version": "1.0.0",
"test":"test"
}
}
beans
[
{
"context": "application:8080:management",
"parent": "application:8080",
"beans": [
{
"bean": "embeddedServletContainerFactory",
"aliases": [
],
"scope": "singleton",
"type": "org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedSe
rvletContainerFactory",
"resource": "null",
"dependencies": [
]
},
{
"bean": "endpointWebMvcChildContextConfiguration",
"aliases": [
],
"scope": "singleton",
"type": "org.springframework.boot.actuate.autoconfigure.EndpointWebMvcChil
dContextConfiguration$$EnhancerBySpringCGLIB$$a4a10f9d",
"resource": "null",
"dependencies": [
]
}
}
]
conditions
{
"positiveMatches": {
"DevToolsDataSourceAutoConfiguration": {
"notMatched": [
{
"condition": "DevToolsDataSourceAutoConfiguration.DevToolsData
SourceCondition",
"message": "DevTools DataSource Condition did not find a singl
e DataSource bean"
}
],
"matched": [ ]
},
"RemoteDevToolsAutoConfiguration": {
"notMatched": [
{
"condition": "OnPropertyCondition",
"message": "@ConditionalOnProperty (spring.devtools.remote.sec
ret) did not find property 'secret'"
}
],
"matched": [
{
"condition": "OnClassCondition",
"message": "@ConditionalOnClass found required classes 'javax.
servlet.Filter', 'org.springframework.http.server.ServerHttpRequest'; @Conditional
OnMissingClass did not find unwanted class"
}
]
}
}
}
confifigprops
{
...
"environmentEndpoint": {
"prefix": "endpoints.env",
"properties": {
"id": "env",
"sensitive": true,
"enabled": true
}
},
"spring.http.multipart-org.springframework.boot.autoconfigure.web.MultipartPrope
rties": {
"prefix": "spring.http.multipart",
"properties": {
"maxRequestSize": "10MB",
"fileSizeThreshold": "0",
"location": null,
"maxFileSize": "1MB",
"enabled": true,
"resolveLazily": false
}
},
"infoEndpoint": {
"prefix": "endpoints.info",
"properties": {
"id": "info",
"sensitive": false,
"enabled": true
}
}
...
}
env
{
"profiles": [
],
"server.ports": {
"local.management.port": 8088,
"local.server.port": 8080
},
"servletContextInitParams": {
},
"systemProperties": {
"com.sun.management.jmxremote.authenticate": "false",
"java.runtime.name": "Java(TM) SE Runtime Environment",
"spring.output.ansi.enabled": "always",
"sun.boot.library.path": "C:\\Program Files\\Java\\jdk1.8.0_101\\jre\\bin",
"java.vm.version": "25.101-b13",
"java.vm.vendor": "Oracle Corporation",
"java.vendor.url": "http://java.oracle.com/",
"java.rmi.server.randomIDs": "true",
"path.separator": ";",
"java.vm.name": "Java HotSpot(TM) 64-Bit Server VM",
"file.encoding.pkg": "sun.io",
"user.country": "CN",
"user.script": "",
"sun.java.launcher": "SUN_STANDARD",
"sun.os.patch.level": "",
"PID": "5268",
"com.sun.management.jmxremote.port": "60093",
"java.vm.specification.name": "Java Virtual Machine Spe
/env/{name} ⽤法
heapdump
httptrace
{
"traces": [
{
"timestamp": "2018-11-21T12:42:25.333Z",
"principal": null,
"session": null,
"request": {
"method": "GET",
"uri": "http://localhost:8080/actuator/heapdump",
"headers": {
"cookie": [
"Hm_lvt_0fb30c642c5f6453f17d881f529a1141=1513076406,151496
1720,1515649377; Hm_lvt_6d8e8bb59814010152d98507a18ad229=1515247964,1515296008,151
5672972,1516086283; UM_distinctid=1647364371ef6-003ab9d0469ea5-b7a103e-100200-1647
364371f104; CNZZDATA1260945749=232252692-1513233181-%7C1537492730"
],
"accept-language": [
"zh-CN,zh;q=0.9"
],
GitChat
"upgrade-insecure-requests": [
"1"
],
"host": [
"localhost:8080"
],
"connection": [
"keep-alive"
],
"accept-encoding": [
"gzip, deflate, br"
],
"accept": [
"text/html,application/xhtml+xml,application/xml;q=0.9,ima
ge/webp,image/apng,*/*;q=0.8"
],
"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"
]
},
"remoteAddress": null
},
"response": {
"status": 200,
"headers": {
"Accept-Ranges": [
"bytes"
],
"Content-Length": [
"39454385"
],
"Date": [
"Wed, 21 Nov 2018 12:42:25 GMT"
],
"Content-Type": [
"application/octet-stream"
]
}
},
"timeTaken": 1380
},
{
...
},
...
]
}
metrics
{
"mem": 337132,
"mem.free": 183380,
"processors": 4,
"instance.uptime": 254552,
"uptime": 259702,
"systemload.average": -1.0,
"heap.committed": 292864,
"heap.init": 129024,
"heap.used": 109483,
"heap": 1827840,
"nonheap.committed": 45248,
"nonheap.init": 2496,
"nonheap.used": 44269,
"nonheap": 0,
"threads.peak": 63,
"threads.daemon": 43,
"threads.totalStarted": 83,
"threads": 46,
"classes": 6357,
"classes.loaded": 6357,
"classes.unloaded": 0,
"gc.ps_scavenge.count": 8,
"gc.ps_scavenge.time": 99,
"gc.ps_marksweep.count": 1,
"gc.ps_marksweep.time": 43,
"httpsessions.max": -1,
"httpsessions.active": 0
}
分類 |
前綴 |
報告內容 |
垃圾收集器器 |
gc.* |
已經發⽣生過的垃圾收集次數,以及垃圾收集所耗費的時間,適⽤用於標記—清理理垃圾收集器器和並⾏行行垃圾收集器器(數據源⾃自java.lang.management.GarbageCollectorMXBean) |
內存 |
mem.* |
分配給應⽤用程序的內存數量量和空閒的內存數量量(數據源⾃自 java.lang. Runtime) |
堆 |
heap.* |
當前內存⽤用量量(數據源⾃自 java.lang.management.MemoryUsage) |
類加載器器 |
classes.* |
JVM 類加載器器加載與卸載的類的數量量(數據源⾃自 java.lang. management.ClassLoadingMXBean) |
系統 |
processors、instance.uptime、uptime、systemload.average |
系統信息,如處理理器器數量量(數據源⾃自 java.lang.Runtime、運⾏行行時間 (數據源⾃自 java.lang.management.RuntimeMXBean)、平均負載 (數據源⾃自 java.lang.management.OperatingSystemMXBean) |
線程池 |
thread.* |
線程、守護線程的數量量,以及 JVM 啓動後的線程數量量峯值(數據源 ⾃ 自 java.lang .management.ThreadMXBean) |
數據源 |
datasource.* |
數據源連接的數量量(源⾃自數據源的元數據,僅當 Spring 應⽤用程序上下⽂文⾥裏里存在 DataSource Bean 的時候纔會有這個信息) |
Tomcat 會話 |
httpsessions.* |
Tomcat 的活躍會話數和最⼤大會話數(數據源⾃自嵌⼊入式 Tomcat 的Bean,僅在使⽤用嵌⼊入式 Tomcat 服務器器運⾏行行應⽤用程序時纔有這個信息) |
HTTP |
counter.status._、gauge.response._ |
多種應⽤用程序服務 HTTP 請求的度量量值與計數器器 |
- 請注意,這⾥的⼀些度量值,⽐如數據源和 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 接⼝會返回所有的可⽤度量值,但你也可能只對某個值感興趣。要獲取單個值,請求時可以在GitChat URL 後加上對應的鍵名。例如,要查看空閒內存⼤⼩,可以向 /metrics/mem.free 發⼀個GET請求,⽐ 如訪問⽹址 http://localhost:8080/actuator/metrics/mem.free,返回:{"mem.free":178123}。
shutdown
management.endpoint.shutdown.enabled=true
curl -X POST "http://localhost:8080/actuator/shutdown"
{
"message": "Shutting down, bye..."
}
mappings
{
"/**/favicon.ico": {
"bean": "faviconHandlerMapping"
},
"{[/hello]}": {
"bean": "requestMappingHandlerMapping",
"method": "public java.lang.String com.neo.controller.HelloController.index()"
},
"{[/error]}": {
"bean": "requestMappingHandlerMapping",
"method": "public org.springframework.http.ResponseEntity<java.util.Map<java.l
ang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErr
orController.error(javax.servlet.http.HttpServletRequest)"
}
}
threaddump
{
"threadName": "http-nio-8088-exec-6",
"threadId": 49,
"blockedTime": -1,
"blockedCount": 0,
"waitedTime": -1,
"waitedCount": 2,
"lockName": "java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionOb
ject@1630a501",
"lockOwnerId": -1,
"lockOwnerName": null,
"inNative": false,
"suspended": false,
"threadState": "WAITING",
"stackTrace": [
{
"methodName": "park",
"fileName": "Unsafe.java",
"lineNumber": -2,
"className": "sun.misc.Unsafe",
"nativeMethod": true
},
...
{
"methodName": "run",
"fileName": "TaskThread.java",
"lineNumber": 61,
"className": "org.apache.tomcat.util.threads.TaskThread$WrappingRunnable",
"nativeMethod": false
}
...
],
"lockInfo": {
"className": "java.util.concurrent.locks.AbstractQueuedSynchronizer$Conditio
nObject",
"identityHashCode": 372286721
}
}
...
]