在Spring Boot的众多Starter POMs中有一个特殊的模块,它不同于其他模块那样大多用于开发业务功能或是连接一些其他外部资源。它完全是一个用于暴露自身信息的模块,所以很明显,它的主要作用是用于监控与管理,它就是:spring-boot-starter-actuator
。
spring-boot-starter-actuator
模块的实现对于实施微服务的中小团队来说,可以有效地减少监控系统在采集应用指标时的开发量。当然,它也并不是万能的,有时候我们也需要对其做一些简单的扩展来帮助我们实现自身系统个性化的监控需求。下面,在本文中,我们将详解的介绍一些关于spring-boot-starter-actuator
模块的内容,包括它的原生提供的端点以及一些常用的扩展和配置方式。
初识Actuator
下面,我们可以通过对快速入门中实现的Spring Boot应用增加spring-boot-starter-actuator
模块功能,来对它有一个直观的认识。
在现有的Spring Boot应用中引入该模块非常简单,只需要在pom.xml
的dependencies
节点中,新增spring-boot-starter-actuator
的依赖即可,具体如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
通过增加该依赖之后,重新启动应用。此时,我们可以在控制台中看到如下图所示的输出:
上图显示了一批端点定义,这些端点并非我们自己在程序中创建,而是由spring-boot-starter-actuator
模块根据应用依赖和配置自动创建出来的监控和管理端点。通过这些端点,我们可以实时的获取应用的各项监控指标,比如:访问/health
端点,我们可以获得如下返回的应用健康信息:
{
"status": "UP",
"diskSpace": {
"status": "UP",
"total": 491270434816,
"free": 383870214144,
"threshold": 10485760
}
}
原生端点
通过在快速入门示例中添加spring-boot-starter-actuator
模块,我们已经对它有了一个初步的认识。接下来,我们详细介绍一下spring-boot-starter-actuator
模块中已经实现的一些原生端点。如果根据端点的作用来说,我们可以原生端点分为三大类:
- 应用配置类:获取应用程序中加载的应用配置、环境变量、自动化配置报告等与Spring Boot应用密切相关的配置类信息。
- 度量指标类:获取应用程序运行过程中用于监控的度量指标,比如:内存信息、线程池信息、HTTP请求统计等。
- 操作控制类:提供了对应用的关闭等操作类功能。
下面我们来详细了解一下这三类端点都分别可以为我们提供怎么样的有用信息和强大功能,以及我们如何去扩展和配置它们。
应用配置类
由于Spring Boot为了改善传统Spring应用繁杂的配置内容,采用了包扫描和自动化配置的机制来加载原本集中于xml文件中的各项内容。虽然这样的做法,让我们的代码变得非常简洁,但是整个应用的实例创建和依赖关系等信息都被离散到了各个配置类的注解上,这使得我们分析整个应用中资源和实例的各种关系变得非常的困难。而这类端点就可以帮助我们轻松的获取一系列关于Spring 应用配置内容的详细报告,比如:自动化配置的报告、Bean创建的报告、环境属性的报告等。
-
/autoconfig:该端点用来获取应用的自动化配置报告,其中包括所有自动化配置的候选项。同时还列出了每个候选项自动化配置的各个先决条件是否满足。所以,该端点可以帮助我们方便的找到一些自动化配置为什么没有生效的具体原因。该报告内容将自动化配置内容分为两部分:
-
positiveMatches
中返回的是条件匹配成功的自动化配置 -
negativeMatches
中返回的是条件匹配不成功的自动化配置 -
{ "positiveMatches": { // 条件匹配成功的 "EndpointWebMvcAutoConfiguration": [ { "condition": "OnClassCondition", "message": "@ConditionalOnClass classes found: javax.servlet.Servlet,org.springframework.web.servlet.DispatcherServlet" }, { "condition": "OnWebApplicationCondition", "message": "found web application StandardServletEnvironment" } ], ... }, "negativeMatches": { // 条件不匹配成功的 "HealthIndicatorAutoConfiguration.DataSourcesHealthIndicatorConfiguration": [ { "condition": "OnClassCondition", "message": "required @ConditionalOnClass classes not found: org.springframework.jdbc.core.JdbcTemplate" } ], ... } }
从如上示例中我们可以看到,每个自动化配置候选项中都有一系列的条件,比如上面没有成功匹配的
HealthIndicatorAutoConfiguration.DataSourcesHealthIndicatorConfiguration
配置,它的先决条件就是需要在工程中包含org.springframework.jdbc.core.JdbcTemplate
类,由于我们没有引入相关的依赖,它就不会执行自动化配置内容。所以,当我们发现有一些期望的配置没有生效时,就可以通过该端点来查看没有生效的具体原因。 -
/beans:该端点用来获取应用上下文中创建的所有Bean。
[ { "context": "hello:dev:8881", "parent": null, "beans": [ { "bean": "org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration$DispatcherServletConfiguration", "scope": "singleton", "type": "org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration$DispatcherServletConfiguration$$EnhancerBySpringCGLIB$$3440282b", "resource": "null", "dependencies": [ "serverProperties", "spring.mvc.CONFIGURATION_PROPERTIES", "multipartConfigElement" ] }, { "bean": "dispatcherServlet", "scope": "singleton", "type": "org.springframework.web.servlet.DispatcherServlet", "resource": "class path resource [org/springframework/boot/autoconfigure/web/DispatcherServletAutoConfiguration$DispatcherServletConfiguration.class]", "dependencies": [] } ] } ]
-
如上示例中,我们可以看到在每个bean中都包含了下面这几个信息:
- bean:Bean的名称
- scope:Bean的作用域
- type:Bean的Java类型
- reource:class文件的具体路径
- dependencies:依赖的Bean名称
-
/configprops:该端点用来获取应用中配置的属性信息报告。从下面该端点返回示例的片段中,我们看到返回了关于该短信的配置信息,
prefix
属性代表了属性的配置前缀,properties
代表了各个属性的名称和值。所以,我们可以通过该报告来看到各个属性的配置路径,比如我们要关闭该端点,就可以通过使用endpoints.configprops.enabled=false
来完成设置。{ "configurationPropertiesReportEndpoint": { "prefix": "endpoints.configprops", "properties": { "id": "configprops", "sensitive": true, "enabled": true } }, ... }
/env:该端点与
/configprops
不同,它用来获取应用所有可用的环境属性报告。包括:环境变量、JVM属性、应用的配置配置、命令行中的参数。从下面该端点返回的示例片段中,我们可以看到它不仅返回了应用的配置属性,还返回了系统属性、环境变量等丰富的配置信息,其中也包括了应用还没有没有使用的配置。所以它可以帮助我们方便地看到当前应用可以加载的配置信息,并配合@ConfigurationProperties
注解将它们引入到我们的应用程序中来进行使用。另外,为了配置属性的安全,对于一些类似密码等敏感信息,该端点都会进行隐私保护,但是我们需要让属性名中包含:password、secret、key这些关键词,这样该端点在返回它们的时候会使用*
来替代实际的属性值。{ "profiles": [ "dev" ], "server.ports": { "local.server.port": 8881 }, "servletContextInitParams": { }, "systemProperties": { "idea.version": "2016.1.3", "java.runtime.name": "Java(TM) SE Runtime Environment", "sun.boot.library.path": "C:\\Program Files\\Java\\jdk1.8.0_91\\jre\\bin", "java.vm.version": "25.91-b15", "java.vm.vendor": "Oracle Corporation", ... }, "systemEnvironment": { "configsetroot": "C:\\WINDOWS\\ConfigSetRoot", "RABBITMQ_BASE": "E:\\tools\\rabbitmq", ... }, "applicationConfig: [classpath:/application-dev.properties]": { "server.port": "8881" }, "applicationConfig: [classpath:/application.properties]": { "server.port": "8885", "spring.profiles.active": "dev", "info.app.name": "spring-boot-hello", "info.app.version": "v1.0.0", "spring.application.name": "hello" } }
/mappings:该端点用来返回所有Spring MVC的控制器映射关系报告。从下面的示例片段中,我们可以看该报告的信息与我们在启用Spring MVC的Web应用时输出的日志信息类似,其中
bean
属性标识了该映射关系的请求处理器,method
属性标识了该映射关系的具体处理类和处理函数。{ "/webjars/**": { "bean": "resourceHandlerMapping" }, "/**": { "bean": "resourceHandlerMapping" }, "/**/favicon.ico": { "bean": "faviconHandlerMapping" }, "{[/hello]}": { "bean": "requestMappingHandlerMapping", "method": "public java.lang.String com.didispace.web.HelloController.index()" }, "{[/mappings || /mappings.json],methods=[GET],produces=[application/json]}": { "bean": "endpointHandlerMapping", "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()" }, ... }
/info:该端点用来返回一些应用自定义的信息。默认情况下,该端点只会返回一个空的json内容。我们可以在
application.properties
配置文件中通过info
前缀来设置一些属性,比如下面这样:info.app.name=spring-boot-hello info.app.version=v1.0.0
再访问
/info
端点,我们可以得到下面的返回报告,其中就包含了上面我们在应用自定义的两个参数。{ "app": { "name": "spring-boot-hello", "version": "v1.0.0" } }