Spring Boot(八):Spring Boot的监控法宝:Actuator


在日常项目中,除了开发过程比较重要以外,实际上运维过程也尤为重要。而Spring Boot 也为我们考虑到了这一点,它为我们提供了Actuator这一组件,帮助我们

监控、管理应用程序

正如官网中所说的那样,它可以通过很小的动作产生巨大的变化


一起来探索一下~


一 原理


01. 什么是Actuator


Spring Boot Actuator,可在您将应用程序投入生产时帮助您监控和管理应用程序。分别支持HTTPJMX两类端点。


02. 支持哪些监控项


总得来说,分为三类:

1)应用配置类:获取应用程序中加载的应用配置、环境变量、自动化配置报告等与Spring Boot应用密切相关的配置类信息


2)度量指标类:获取应用程序运行过程中用于监控的度量指标,比如:内存信息、线程池信息、HTTP请求统计等


3)操作控制类:提供了对应用的关闭等操作类功能


常用端点如下:


<code>1)auditevents 公开当前应用程序的审核事件信息

2) beans 该端点用来获取应用上下文中创建的所有Bean


3) caches 展示可用的缓存

4)conditions 显示在配置和自动配置类上评估的条件以及它们匹配或不匹配的原因

5)configprops 所有@ConfigurationProperties的配置列表

6)flyway 显示已应用的所有Flyway数据库迁移。

7)env 返回当前的环境变量

8)health 健康状况

9)httptrace 查看HTTP请求响应明细(默认100条)

10)info 展示服务应用信息

11)loggers 查看日志配置,支持动态修改日志级别

12)liquibase 显示已应用的所有Liquibase数据库迁移

13)metrics 显示当前应用程序的“指标”信息

14)mappings 显示所有@RequestMapping请求列表

15)scheduledtasks 显示服务中的所有定时任务

16)sessions 允许从Spring Session支持的会话存储中检索和删除用户会话

17)shutdown 可以使服务优雅的关闭,默认没有开启


18)threaddump 执行线程转储
/<code>

参考:Spring Boot官网之Actuator部分


注意:Spring Boot Actuator也支持prometheus、jolokia和integrationgraph,但若要使用它们,分别需要引入对应的依赖,才能正常使用


03. 如何实现


1)引入依赖


简单的使用呢,只需要引入以下依赖,启动服务即可


<code><dependencies>    
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-actuator/<artifactid>
/<dependency>
/<dependencies>/<code>


2)重启服务,访问页面


访问地址http://localhost:8888/actuator,便可以看到各个监控url,访问对应的url,就可以看到对应的监控参数
需要注意的是,为了安全起见,http默认只暴露health和info两个节点


Spring Boot(八):Spring Boot的监控法宝:Actuator

04. 常用配置项


我们可以根据需要,通过配置项进行节点的开启与关闭设置


1)开启单个endPoint端点

<code>management.endpoints.jmx.exposure.exclude=
management.endpoints.jmx.exposure.include=*

management.endpoints.web.exposure.exclude=
management.endpoints.web.exposure.include=info, health/<code>


示例:

<code>#1、只开启info端点的配置
#关闭所有端点
management.endpoints.enabled-by-default=false
#开启info端点
management.endpoint.info.enabled=true/<code>


这两个配置项的结合,表示只开启了info端点


2)暴露、关闭endpoint端点

<code>management.endpoints.jmx.exposure.exclude=
management.endpoints.jmx.exposure.include=*

management.endpoints.web.exposure.exclude=
management.endpoints.web.exposure.include=info, health/<code>


如上所示,前两个配置项表示对jmx端点的关闭与开启的整体配置,后两项配置则是对http端点的关闭与开启的整体配置。


3)对于监控访问地址特定配置


从第3小节中,我们可以看到,监控默认的HTTP访问地址为


<code>服务ip:服务端口/actuator//<code>


在实际生产中,我们也可以通过配置,将监控地址配置为与原服务不同的某个特定地址


这样的话,我们就可以只给外部提供我们的服务地址,而不需要担心他们也监控我们的服务的作用了。


经常使用到的配置项如下所示:


<code>management.server.address=监控服务ip
management.server.port=监控服务端口
management.endpoints.web.base-path=访问的baseUrl
management.endpoints.web.path-mapping.=访问路径/<code>


我们在项目中添加如下配置


<code>#监控服务ip
management.server.address=127.0.0.1
#监控服务端口
management.server.port=8008
#访问的baseUrl(默认为/actuator)
management.endpoints.web.base-path=/myActuator
#对某个特定端点的路径配置

management.endpoints.web.path-mapping.health=/monitor/health/<code>


页面访问,原来的请求地址已无法访问,而我们配置的地址已经生效


Spring Boot(八):Spring Boot的监控法宝:Actuator


04. 源码分析


总得来说,Spring Boot Actuator是通过定制不同的endPoint,进行各个监控项进行监控的
具体点的话,我们跟着源码走一波~


如下所示,会通过EndpointDiscoverer.discoverEndpoints()方法进行各个监控项的加载

Spring Boot(八):Spring Boot的监控法宝:Actuator


1)加载endPointBean


通过调用createEndpointBeans()方法,加载所有带有@EndPoint注解的bean

Spring Boot(八):Spring Boot的监控法宝:Actuator


我们可以看到,该方法时是从上下文中获取带有@EndPoint注解的bean,检查是否有重复id的endPointBean,若未出现,则将结果返回


2)加载EndPointExtensionBean

通过调用addExtensionBeans()方法,加载所有带有@EndPointExtension注解的bean,同样检查是否出现重复id的EndPointExtensionBean,若未出现,则将结果返回

Spring Boot(八):Spring Boot的监控法宝:Actuator


需要说明的是,该 EndpointExtension类是对对应的Endpoint 类的扩展。

Spring Boot(八):Spring Boot的监控法宝:Actuator


目前有三个这样的Bean:


CachesEndpointWebExtension

HealthEndpointWebExtension

EnvironmentEndpointWebExtension


其中,HealthEndpointWebExtension的定义如下

Spring Boot(八):Spring Boot的监控法宝:Actuator

我们可以看到,HealthEndpointWebExtension通过标签endpint指向HealthEndPoint类


接着上一步,进入addExtensionBean()方法,我们看到,该方法会分别对EndpointExtension和extensionBean进行判断


Spring Boot(八):Spring Boot的监控法宝:Actuator

a 判断endpointExtension


进入扩展bean判断,只有该扩展类对应的filter与对应的endpointBean保持一致,并且对应的endpointBean并没有被关闭掉,才能将其加入到endpointBean中


Spring Boot(八):Spring Boot的监控法宝:Actuator

b 判断 endpointbean


是否匹配对应的 filter,此 bean 是否被 exclude 了!(配置文件配置),同时判断 bean 上的注解是否匹配当前 supplier


Spring Boot(八):Spring Boot的监控法宝:Actuator


3)处理获取到的endPointBeans


这个过程通过调用convertToEndPoints()方法,分别加载各个endPoint类的操作方法,并将各个endPoint的id以/actuator为前缀的形式映射为URL(若有特定配置,前缀为配置项的值)


例如,默认情况下,health端点映射为

<code>/actuator/health/<code>


4)特定端点特定处理


当收到某个端点的请求时,再分别进行各个监控点的判断,并展示结果。
如,当请求health节点,即调用url:http://localhost:8888/actuator/health时,会按照以下步骤执行

a 首先会调用invoke()方法,获取到对应的url映射地址

Spring Boot(八):Spring Boot的监控法宝:Actuator

b 然后通过反射机制获取到对应节点的操作类与方法

Spring Boot(八):Spring Boot的监控法宝:Actuator

通过上图,我们发现,获取到的需要检查健康状况的分别为磁盘空间、数据库连接状态以及redis连接状态


c 分别执行各个操作方法,返回结果


那么接下来,就会分别进入各个指示器,调用对应的doHealthCheck()方法进行相应检查处理
举个例子,以下是磁盘的健康检查类的doHealthCheck()方法,它主要获取磁盘可用空间等信息,并返回结果

Spring Boot(八):Spring Boot的监控法宝:Actuator


好了,以上就是我们对于Spring Boot Actuator的监控原理进行了跟踪梳理。其他的端点,也基本类似,大家不妨也跟踪源码,了解一下他们的具体处理机制


当然,对于一些监控项,也支持响应式,就是说,只要某个监控项的值发生了变化,就会实时更新数据。本节作为了解监控特性的第一篇,就先不介绍了,以后有机会可以专门再来一篇


二 实战环节


01. 快速实现


很简单,请参照第一节中 03如何实现的操作步骤快速实现一个具有监控功能的应用程序,分为以下三步:

1)引入依赖

2)添加配置

3)运行服务,查看节点


02. 功能扩展


Spring Boot Actuator为我们提供的诸多节点,已可以支持我们的大部分的监控功能了,但若是我们还想要扩展的话,我们可以分别通过添加自定义endpoint自定义健康状况检查项以及自定义健康状态进行监控项等进行扩展


1)自定义endpoint


如果需要自定义节点,只需要定义一个带有注解@Endpoint的类,然后结分别合@ReadOperation, @WriteOperation, or @DeleteOperation定义具体的方法即可
如下所示

<code>@Endpoint(id = "hello")
@Component
public class MyEndPoint {
@ReadOperation
public String getHello(){
return "Hello~ World";
}
/**
* 定义带有参数的
* @param name
* @return
*/
@ReadOperation

public String getHelloWithName(@Selector String name){
return "Hello~"+name;
}
@WriteOperation
public String postHello(){
return "post Hello";
}
@DeleteOperation
public String deleteHello(){
return "delete Hello";
}
}/<code>


页面访问,你会发现,便多了我们新增的两个节点


Spring Boot(八):Spring Boot的监控法宝:Actuator


2)自定义健康状况检查项

Spring Boot Actuator默认支持以下各项的健康检查


Spring Boot(八):Spring Boot的监控法宝:Actuator


它们均通过直接或间接实现HealthIndicator接口来处理各个服务项进行健康状况检查请求


那么,我们若要自定义自己健康状况检查项的话,同样只需要实现HealthIndicator接口,并重写对应的health()方法即可


比如我们现在需要增加一个监控库存中是否还有足够的苹果的时候,我们就可以定义如下所示的监控类

<code>/**
* 监控库存中是否还有足够的苹果
*/
@Component
public class MyIndicator implements HealthIndicator {
private long count = 50; //实际中生产中,可以从数据库中获取苹果的数量
@Override
public Health health() {
Health health;
if (count<=5){
health = Health.up()
.withDetail("count",count)
.withDetail("message","糟糕,苹果库存不足啦~需要备货啦~")
.build();
}else {
health = Health.down()
.withDetail("count",count)
.withDetail("message","我们还有足够的苹果哟~")
.build();
}
return health;
}
}/<code>


重启服务,页面请求health的url


Spring Boot(八):Spring Boot的监控法宝:Actuator


健康检查项中就多了我们自定义的监控项


3)自定义健康状况类型


关于健康状态类型,actuator内置以下几种HTTP状态码:


<code>StatusMappingDOWN 503
OUT_OF_SERVICE 503
UP 200
UNKNOWN 200/<code>


我们也可以通过如下配置添加自定义状态:


<code>#添加状态FATAL
management.health.status.order=FATAL, DOWN, OUT_OF_SERVICE, UNKNOWN, UP
#映射状态的状态码(即FATAL对应的状态码绑定为503)
management.health.status.http-mapping.FATAL=503/<code>


如果你需要更多的控制,也可以通过定义自己的 HealthStatusHttpMapper bean进行实现


三 总结 总而言之


今天主要聊了聊作为Spring Boot的四大法宝之一的 监控特性

主要分别从认识Spring Boot Actuator如何使用使用它实现监控功能,进而跟踪源码探索底层原理,最后通过自定义节点或者监控项等方式进行功能扩展


spring-boot-starter-actuator模块的实现对于实施微服务的中小团队来说,可以有效地减少监控系统在采集应用指标时的开发量。通常我们会使用它所提供的http的API进行监控端或者管理端的功能集成开发,从而实现服务各项指标的监控,尤其方便

当然,我们也可以通过它的各个端点的实现机制,定义我们自己的endPoint或者对于已有的endPoint功能进行进行相应的扩展,实现我们自身系统个性化的监控需求

因为监控项中暴露了很多服务参数,实际过程中,我们通常是借助Spring Boot Security来进行安全配置。留给大家进行探索咯~


看完文章,我想你肯定掌握了以下几点:


1、Spring Boot Actuator的监控项


2、如何使用Spring Boot Actuator进行应用程序的监控


3、Spring Boot Actuator的监控原理


4、如何扩展监控项,实现定制化监控功能


嗯,就这样。每天学习一点,时间会见证你的强大~


下期预告:
Spring Boot(九):Spring Boot 安全法宝-Spring Security


本期项目代码已上传到github~有需要的可以参考

<code>https://github.com/wangjie0919/Spring-Boot-Notes/<code>


往期精彩回顾



您的关注 是我们持续更新的动力~


分享到:


相關文章: