- 1. 如何添加
- 2. actuator 的原生端點(API)
- 2.1 應用類配置
- 2.1.1 http://localhost:8080/actuator/conditions
- 2.1.2 http://localhost:8080/actuator/beans
- 2.1.3 http://localhost:8080/actuator/configprops
- 2.1.4 http://localhost:8080/actuator/env & http://localhost:8080/actuator/env/{toMatch}
- 2.1.5 http://localhost:8080/actuator/info
- 2.1.6 http://localhost:8080/actuator/mappings
- 2.2 度量指標類
- 2.2.1 http://localhost:8080/actuator/health
- 2.2.2 http://localhost:8080/actuator/auditevents
- 2.2.3 http://localhost:8080/actuator/loggers & http://localhost:8080/actuator/loggers/{name}
- 2.2.4 http://localhost:8080/actuator/metrics & http://localhost:8080/actuator/metrics/{requiredMetricName}
- 2.2.5 http://localhost:8080/actuator/heapdump
- 2.2.6 http://localhost:8080/actuator/threaddump
- 2.2.7 http://localhost:8080/actuator/scheduledtasks
- 2.2.8 http://localhost:8080/actuator/httptrace
- 2.3 操作類
- 2.1 應用類配置
- 3. Actuator 在 Spring Boot 1.X 和Spring Boot 2.X 的差異
這是一篇結合Spring Boot 2.X 介紹actuator['æktjueitə] 入門的文檔
官方文檔: https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/actuator-api/html/
1. 如何添加
只需要在原來的POM中添加如下maven依賴:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
添加完畢后,在啟動的時候你就會發現如下的日子輸出:
2018-09-22 00:33:19.713 INFO 22802 --- [ restartedMain] o.s.b.a.e.web.EndpointLinksResolver : Exposing 2 endpoint(s) beneath base path '/actuator' 2018-09-22 00:33:19.720 INFO 22802 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/health],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:33:19.721 INFO 22802 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/info],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:33:19.721 INFO 22802 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto protected java.util.Map<java.lang.String, java.util.Map<java.lang.String, org.springframework.boot.actuate.endpoint.web.Link>> org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping.links(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 2018-09-22 00:33:19.750 INFO 22802 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
我們會發現Actuator 幫我添加了3個API
- /actuator
- /actuator/health
- /actuator/info
/actuator
概括actuator所有的API,templated -> 標示當前URL是否是一個模板
{ "_links": { "self": { "href": "http://localhost:8080/actuator", "templated": false }, "health": { "href": "http://localhost:8080/actuator/health", "templated": false }, "info": { "href": "http://localhost:8080/actuator/info", "templated": false } } }
/actuator/health
{ status: "UP" }
/actuator/info
{ }
后兩個API幾乎沒有什么屬性返回,別急,等我們項目集成了更多的Spring Cloud 插件之后,里面就會有更多的屬性了。
應該還會有人有疑問,為什么原生的監控插件怎么就返回這么幾個API呀,其實這個只是默認配置,就像下圖,默認的配置如下:
management.endpoints.web.exposure.include= ["health","info"]
如果想加載全部的API只需要將這個參數設置成 * 就行了
management.endpoints.web.exposure.include = *

這個時候我們再啟動程序的時候就會看到下邊這些輸出:
2018-09-22 00:43:30.917 INFO 22845 --- [ restartedMain] o.s.b.a.e.web.EndpointLinksResolver : Exposing 14 endpoint(s) beneath base path '/actuator' 2018-09-22 00:43:30.930 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/auditevents],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.931 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/beans],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.931 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/health],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.931 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/conditions],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.931 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/configprops],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.931 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/env],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.931 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/env/{toMatch}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.932 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/info],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.932 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/loggers/{name}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.932 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/loggers/{name}],methods=[POST],consumes=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.932 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/loggers],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.933 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/heapdump],methods=[GET],produces=[application/octet-stream]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.933 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/threaddump],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.933 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/metrics/{requiredMetricName}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.933 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/metrics],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.933 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/scheduledtasks],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.933 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/httptrace],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.934 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/mappings],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2018-09-22 00:43:30.934 INFO 22845 --- [ restartedMain] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto protected java.util.Map<java.lang.String, java.util.Map<java.lang.String, org.springframework.boot.actuate.endpoint.web.Link>> org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping.links(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 2018-09-22 00:43:30.979 INFO 22845 --- [ restartedMain] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
/actuator
同時這個API也將增加新的成員
{ "_links": { "self": { "href": "http://localhost:8080/actuator", "templated": false }, "auditevents": { "href": "http://localhost:8080/actuator/auditevents", "templated": false }, "beans": { "href": "http://localhost:8080/actuator/beans", "templated": false }, "health": { "href": "http://localhost:8080/actuator/health", "templated": false }, "conditions": { "href": "http://localhost:8080/actuator/conditions", "templated": false }, "configprops": { "href": "http://localhost:8080/actuator/configprops", "templated": false }, "env": { "href": "http://localhost:8080/actuator/env", "templated": false }, "env-toMatch": { "href": "http://localhost:8080/actuator/env/{toMatch}", "templated": true }, "info": { "href": "http://localhost:8080/actuator/info", "templated": false }, "loggers-name": { "href": "http://localhost:8080/actuator/loggers/{name}", "templated": true }, "loggers": { "href": "http://localhost:8080/actuator/loggers", "templated": false }, "heapdump": { "href": "http://localhost:8080/actuator/heapdump", "templated": false }, "threaddump": { "href": "http://localhost:8080/actuator/threaddump", "templated": false }, "metrics-requiredMetricName": { "href": "http://localhost:8080/actuator/metrics/{requiredMetricName}", "templated": true }, "metrics": { "href": "http://localhost:8080/actuator/metrics", "templated": false }, "scheduledtasks": { "href": "http://localhost:8080/actuator/scheduledtasks", "templated": false }, "httptrace": { "href": "http://localhost:8080/actuator/httptrace", "templated": false }, "mappings": { "href": "http://localhost:8080/actuator/mappings", "templated": false } } }
是不是感覺接口增加了好多,是不是突然感覺無從下手,不要捉急,下邊我們就來細細道來這些接口的作用。
2. actuator 的原生端點(API)
全部的API(endpoints): https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html
Actuator的原生API有很多,但是大體上可以分為以下三類,
- 應用配置類:應用配置/環境變量/自動化配置等
- 度量指標類:運行時監控到的指標,如內存,線程池,HTTP統計信息等
- 操作控制類:如對應用關閉等操作類
2.1 應用類配置
2.1.1 http://localhost:8080/actuator/conditions
該端點用來獲取應用的自動化配置報告,其中包括所有自動化配置的候選項。同時還列出了每個候選項自動化配置的各個先決條件是否滿足。所以,該端點可以幫助我們方便的找到一些自動化配置為什么沒有生效的具體原因。該報告內容將自動化配置內容分為三部分:
- positiveMatches中返回的是條件匹配成功的自動化配置
- negativeMatches中返回的是條件匹配不成功的自動化配置
- unconditionalClasses
簡化起見,我們每個部分返回兩個節點,結構如下:
{ "contexts": { "application": { "positiveMatches": { "AuditAutoConfiguration#auditListener": [ { "condition": "OnBeanCondition", "message": "@ConditionalOnMissingBean (types: org.springframework.boot.actuate.audit.listener.AbstractAuditListener; SearchStrategy: all) did not find any beans" } ], "AuditAutoConfiguration.AuditEventRepositoryConfiguration": [ { "condition": "OnBeanCondition", "message": "@ConditionalOnMissingBean (types: org.springframework.boot.actuate.audit.AuditEventRepository; SearchStrategy: all) did not find any beans" } ] }, "negativeMatches": { "RabbitHealthIndicatorAutoConfiguration": { "notMatched": [ { "condition": "OnClassCondition", "message": "@ConditionalOnClass did not find required class 'org.springframework.amqp.rabbit.core.RabbitTemplate'" } ], "matched": [] }, "RemoteDevToolsAutoConfiguration": { "notMatched": [ { "condition": "OnPropertyCondition", "message": "@ConditionalOnProperty (spring.devtools.remote.secret) did not find property 'secret'" } ], "matched": [ { "condition": "OnClassCondition", "message": "@ConditionalOnClass found required classes 'javax.servlet.Filter', 'org.springframework.http.server.ServerHttpRequest'; @ConditionalOnMissingClass did not find unwanted class" } ] } }, "unconditionalClasses": [ "org.springframework.boot.actuate.autoconfigure.management.HeapDumpWebEndpointAutoConfiguration", "org.springframework.boot.actuate.autoconfigure.scheduling.ScheduledTasksEndpointAutoConfiguration" ] } } }
2.1.2 http://localhost:8080/actuator/beans
該接口返回當前上下文中配置的所有的Bean,從返回的數據來看,包含以下屬性:
- 外層是Bean的名稱
- aliases: 別名
- scope:Bean作用域
- type:Bean的Java類型
- resource:class文件的路徑
- dependencies:所依賴的其他Bean
接口返回信息如下:
{ "contexts": { "application": { "beans": { "endpointCachingOperationInvokerAdvisor": { "aliases": [], "scope": "singleton", "type": "org.springframework.boot.actuate.endpoint.invoker.cache.CachingOperationInvokerAdvisor", "resource": "class path resource [org/springframework/boot/actuate/autoconfigure/endpoint/EndpointAutoConfiguration.class]", "dependencies": [ "environment" ] }, "defaultServletHandlerMapping": { "aliases": [], "scope": "singleton", "type": "org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport$EmptyHandlerMapping", "resource": "class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]", "dependencies": [] } }, "parentId": null } } }
2.1.3 http://localhost:8080/actuator/configprops
該接口用來返回應用中配置的屬性和值,prefix代表前綴,如我們在前邊配置的 management.endpoints.web.exposure.include = *
{ "contexts": { "application": { "beans": { "management.trace.http-org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceProperties": { "prefix": "management.trace.http", "properties": { "include": [ "TIME_TAKEN", "REQUEST_HEADERS", "RESPONSE_HEADERS", "COOKIE_HEADERS" ] } }, "management.endpoints.web-org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties": { "prefix": "management.endpoints.web", "properties": { "pathMapping": {}, "exposure": { "include": [ "*" ], "exclude": [] }, "basePath": "/actuator" } } }, "parentId": null } } }
2.1.4 http://localhost:8080/actuator/env & http://localhost:8080/actuator/env/{toMatch}
該端點與/configprops不同,它用來獲取應用所有可用的環境屬性報告。包括:環境變量、JVM屬性、應用的配置配置、命令行中的參數。從下面該端點返回的示例片段中,我們可以看到它不僅返回了應用的配置屬性,還返回了系統屬性、環境變量等豐富的配置信息,其中也包括了應用還沒有沒有使用的配置。所以它可以幫助我們方便地看到當前應用可以加載的配置信息,並配合@ConfigurationProperties注解將它們引入到我們的應用程序中來進行使用。另外,為了配置屬性的安全,對於一些類似密碼等敏感信息,該端點都會進行隱私保護,但是我們需要讓屬性名中包含:password、secret、key這些關鍵詞,這樣該端點在返回它們的時候會使用*來替代實際的屬性值。
{ "activeProfiles": [], "propertySources": [ { "name": "server.ports", "properties": { "local.server.port": { "value": 8080 } } }, { "name": "servletContextInitParams", "properties": {} }, { "name": "systemProperties", "properties": { "java.runtime.name": { "value": "Java(TM) SE Runtime Environment" }, "java.runtime.version": { "value": "1.8.0_144-b01" } } }, { "name": "systemEnvironment", "properties": { "PATH": { "value": "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/opt/tomcat9/bi:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/eric/Documents/apps/mongodb.3/bin:/usr/local/opt/apache-maven-3.5/bin", "origin": "System Environment Property \"PATH\"" } } }, { "name": "applicationConfig: [classpath:/application.properties]", "properties": { "management.endpoints.web.exposure.include": { "value": "*", "origin": "class path resource [application.properties]:2:45" } } }, { "name": "refresh", "properties": { "spring.mustache.cache": { "value": "false" } } } ] }
ENV是返回所有的環境參數,如果執行查看其中一個的只需要在后邊加上參數名稱即可。如:
http://localhost:8080/actuator/env/local.server.port
{ "property": { "source": "server.ports", "value": 8080 }, "activeProfiles": [], "propertySources": [ { "name": "server.ports", "property": { "value": 8080 } }, { "name": "servletConfigInitParams" }, { "name": "servletContextInitParams" }, { "name": "systemProperties" }, { "name": "systemEnvironment" }, { "name": "random" }, { "name": "applicationConfig: [classpath:/application.properties]" }, { "name": "refresh" }, { "name": "Management Server" } ] }
2.1.5 http://localhost:8080/actuator/info
展示了關於應用的一般信息,這些信息從編譯文件比如META-INF/build-info.properties或者Git文件比如git.properties或者任何環境的property中獲取。
深度解析:https://blog.csdn.net/qq_26000415/article/details/79234812
使用案例: https://blog.csdn.net/dyc87112/article/details/73739530
2.1.6 http://localhost:8080/actuator/mappings
顯示所有的@RequestMapping路徑
{ "contexts": { "application": { "mappings": { "dispatcherServlets": { "dispatcherServlet": [ { "handler": "ResourceHttpRequestHandler [locations=[class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], ServletContext resource [/], class path resource []], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@68fcd3bb]]", "predicate": "/**/favicon.ico", "details": null } ] }, "servletFilters": [ { "servletNameMappings": [], "urlPatternMappings": [ "/*" ], "name": "webMvcMetricsFilter", "className": "org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter" } ], "servlets": [ { "mappings": [ "/" ], "name": "dispatcherServlet", "className": "org.springframework.web.servlet.DispatcherServlet" } ] }, "parentId": null } } }
2.2 度量指標類
2.2.1 http://localhost:8080/actuator/health
目前返回信息比較簡單,UP 代表當前程序時啟動狀態。
{
"status": "UP"
}
如果我們再配置文件中打開詳細信息的顯示,就會看到如下信息:
management.endpoint.health.show-details=always
{ "status": "UP", "details": { "diskSpace": { "status": "UP", "details": { "total": 499963170816, "free": 294690533376, "threshold": 10485760 } } } }
這些是默認的信息,如果我們想客戶這些信息我們可以:
- 實現HealthIndicator
- 繼承AbstractHealthIndicator抽象類,重寫doHealthCheck方法
當然我們依賴spring-boot-xxx-starter后,一些相關HealthIndicator的實現就會被自動裝配,同樣的相應的信息也會在這個API返回。
常見的HealthIndicator | 作用 |
---|---|
CassandraHealthIndicator | 檢查 Cassandra 數據庫是否啟動 |
DiskSpaceHealthIndicator | 檢查磁盤空間不足 |
DataSourceHealthIndicator | 檢查是否可以獲得連接 DataSource |
ElasticsearchHealthIndicator | 檢查 Elasticsearch 集群是否啟動 |
InfluxDbHealthIndicator | 檢查 InfluxDB 服務器是否啟動 |
JmsHealthIndicator | 檢查 JMS 代理是否啟動 |
MailHealthIndicator | 檢查郵件服務器是否啟動 |
MongoHealthIndicator | 檢查 Mongo 數據庫是否啟動 |
Neo4jHealthIndicator | 檢查 Neo4j 服務器是否啟動 |
RabbitHealthIndicator | 檢查 Rabbit 服務器是否啟動 |
RedisHealthIndicator | 檢查 Redis 服務器是否啟動 |
SolrHealthIndicator | 檢查 Solr 服務器是否已啟動 |
2.2.2 http://localhost:8080/actuator/auditevents
顯示應用暴露的審計事件 (比如認證進入、訂單失敗)
{ "events": [ ] }
2.2.3 http://localhost:8080/actuator/loggers & http://localhost:8080/actuator/loggers/{name}
顯示和修改配置的loggers。它展示了應用中可配置的loggers的列表和相關的日志等級。
{ "levels": [ "OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE" ], "loggers": { "ROOT": { "configuredLevel": "INFO", "effectiveLevel": "INFO" }, "{name}": { "configuredLevel": null, "effectiveLevel": "INFO" } } }
你同樣能夠使用 http://localhost:8080/actuator/loggers/{name} 來展示特定logger的細節。如你可以使用 http://localhost:8080/actuator/loggers/ROOT:
{
"configuredLevel": "INFO",
"effectiveLevel": "INFO"
}
/loggers 這個API不止可以查看Logger等級,還可以修改運行時Logger的等級。
如你可以用POST調用 http://localhost:8080/actuator/loggers/ROOT ,並傳遞如下參數:
{ "configuredLevel": "DEBUG" }

我們再回過頭來查看ROOT的Loggers等級時,已經修改為如下狀態:
{ "configuredLevel": "DEBUG", "effectiveLevel": "DEBUG" }
2.2.4 http://localhost:8080/actuator/metrics & http://localhost:8080/actuator/metrics/{requiredMetricName}
Metrics的可視化: https://bigjar.github.io/2018/08/19/Spring-Boot-Metrics%E7%9B%91%E6%8E%A7%E4%B9%8BPrometheus-Grafana/
這一對不像前邊的幾對API,這一對是前邊的API返回所有你能查看的度量指標,后邊是看某一個度量指標的具體值。
{ "names": [ "jvm.memory.max", "http.server.requests", "process.files.max", "jvm.gc.memory.promoted", "tomcat.cache.hit", "system.load.average.1m", "tomcat.cache.access", "jvm.memory.used", "jvm.gc.max.data.size", "jvm.gc.pause", "jvm.memory.committed", "system.cpu.count", "logback.events", "tomcat.global.sent", "jvm.buffer.memory.used", "tomcat.sessions.created", "jvm.threads.daemon", "system.cpu.usage", "jvm.gc.memory.allocated", "tomcat.global.request.max", "tomcat.global.request", "tomcat.sessions.expired", "jvm.threads.live", "jvm.threads.peak", "tomcat.global.received", "process.uptime", "tomcat.sessions.rejected", "process.cpu.usage", "tomcat.threads.config.max", "jvm.classes.loaded", "jvm.classes.unloaded", "tomcat.global.error", "tomcat.sessions.active.current", "tomcat.sessions.alive.max", "jvm.gc.live.data.size", "tomcat.servlet.request.max", "tomcat.threads.current", "tomcat.servlet.request", "process.files.open", "jvm.buffer.count", "jvm.buffer.total.capacity", "tomcat.sessions.active.max", "tomcat.threads.busy", "process.start.time", "tomcat.servlet.error" ] }
如我們想 jvm.memory.max 具體的值,可以通過下邊的URL查看
http://localhost:8080/actuator/metrics/jvm.memory.max
{ "name": "jvm.memory.max", "description": "The maximum amount of memory in bytes that can be used for memory management", "baseUnit": "bytes", "measurements": [ { "statistic": "VALUE", "value": 5602017279 } ], "availableTags": [ { "tag": "area", "values": [ "heap", "nonheap" ] }, { "tag": "id", "values": [ "Compressed Class Space", "PS Survivor Space", "PS Old Gen", "Metaspace", "PS Eden Space", "Code Cache" ] } ] }
2.2.5 http://localhost:8080/actuator/heapdump
返回一個GZip壓縮的JVM堆dump
介紹HeapDumpWebEndpoint原理: https://www.jianshu.com/p/6df45fed02fa
分析dump文件: https://www.cnblogs.com/liangzs/p/8489321.html
分析dump文件: https://blog.csdn.net/albertfly/article/details/78686408
分析dump文件: https://www.javatang.com/archives/2017/10/30/53562102.html
分析dump文件: https://www.cnblogs.com/toSeeMyDream/p/7151635.html
2.2.6 http://localhost:8080/actuator/threaddump
執行一個線程dump
分析工具和方法: https://blog.csdn.net/hivon/article/details/8331350
{ "threads": [ { "threadName": "DestroyJavaVM", "threadId": 59, "blockedTime": -1, "blockedCount": 0, "waitedTime": -1, "waitedCount": 0, "lockName": null, "lockOwnerId": -1, "lockOwnerName": null, "inNative": false, "suspended": false, "threadState": "RUNNABLE", "stackTrace": [], "lockedMonitors": [], "lockedSynchronizers": [], "lockInfo": null } ] }
2.2.7 http://localhost:8080/actuator/scheduledtasks
顯示應用中的調度任務
{ "cron": [], "fixedDelay": [], "fixedRate": [] }
2.2.8 http://localhost:8080/actuator/httptrace
顯示HTTP足跡,最近100個HTTP request/repsponse
{ "traces": [ { "timestamp": "2018-09-23T05:45:34.642Z", "principal": null, "session": null, "request": { "method": "GET", "uri": "http://localhost:8080/actuator/scheduledtasks", "headers": { "postman-token": [ "bf0a747f-a8dd-433e-90e6-17f869a75d15" ], "host": [ "localhost:8080" ], "connection": [ "keep-alive" ], "cache-control": [ "no-cache" ], "accept-encoding": [ "gzip, deflate" ], "accept": [ "*/*" ], "user-agent": [ "PostmanRuntime/7.3.0" ] }, "remoteAddress": null }, "response": { "status": 200, "headers": { "Transfer-Encoding": [ "chunked" ], "Date": [ "Sun, 23 Sep 2018 05:45:34 GMT" ], "Content-Type": [ "application/vnd.spring-boot.actuator.v2+json;charset=UTF-8" ] } }, "timeTaken": 14 } ] }
2.3 操作類
2.3.1 http://localhost:8080/actuator/shutdown
POST: /shutdown
默認是關閉的,可以通過下邊的配置開啟這個API:
management.endpoint.shutdown.enabled=true

3. Actuator 在 Spring Boot 1.X 和Spring Boot 2.X 的差異
Spring Boot 1.X Actuator 一些屬性的介紹: http://357029540.iteye.com/blog/2392530
3.1 配置Key之間的變化
1.X 屬性 | 2.X 屬性 |
---|---|
endpoints.<id >.* | management.endpoint.<id>.* |
endpoints.cors.* | management.endpoints.web.cors.* |
endpoints.jmx.* | management.endpoints.jmx.* |
management.address | management.server.address |
management.context-path | management.server.servlet.context-path |
management.ssl.* | management.server.ssl.* |
management.port | management.server.port |
3.2 根節點發生了變化
2.X 比1.X 多了一個根路徑: /actuator 。當然你也可以通過management.endpoints.web.base-path
設置一個根節點。如果你設置management.server.servlet.context-path=/management
和management.endpoints.web.base-path=/application
,你就可以在下面的路徑到達終點健康:/management/application/health 。注意context-path
只有在設置了 management.server.port
時才有效。
3.3 一些端點發生變化(API)
- /autoconfig -> 更名為 /conditions
- /docs -> 被廢棄
- /health -> 有一個 management.endpoint.health.show-details 選項 never, always, when-authenticated,而不是依靠 sensitive 標志來確定 health 端點是否必須顯示全部細節。 默認情況下,/actuator/health公開並且不顯示細節。
- /trace -> 更名為 /httptrace
- /dump -> 更名為 /threaddump