本文转载自微信公众号《程序新视界》,作者二师兄丑胖子。转载本文请联系程序新视界公众号。前言看到SpringBootActuator框架的时候,我一直在想,它是干什么的?虽然知道它提供了很多端点,对应用的监控和管理很有帮助,但是如果没有直接的实践案例,还是很吃力的。很难让人信服。直到上一篇《微服务架构:Nacos本地缓存 PK 微服务优雅下线》提到Actuator定义的端点可以用来实现微服务优雅离线的效果,我才发现Actuator真的好用。那么这篇文章就是基于SpringBoot系统如何集成Actuator,如何使用,以及如何自定义一个端点(Endpoint)。SpringBootActuator简介SpringBootActuator是SpringBoot提供的一个功能模块,用于对应用系统进行自省和监控。基于此,开发者可以方便地对应用系统的某些监控指标进行查看、统计、审计和指标采集。Actuator提供基于Http端点或JMX的管理和监控应用程序。刚接触Actuator的朋友通常会有一个疑问。Actuator可以通过Http端点访问,那么它和SpringWeb提供的@Controller对外服务有什么区别呢?它们都可以通过Http访问应用,只是Functions的定义不同。上面说到Actuator通常用于监控和操作应用程序本身的运行状态,而@Controller更多的是用在业务层面。通过与@Controller对比,你可能更容易理解Actuator的作用。Actuator默认函数Actuator提供了一些默认的REST接口,基于这些接口我们可以方便的了解应用程序的运行状态。其中一些端口是敏感的,需要在指定的权限下访问。通过Actuator可以监控应用的Health信息、Info应用信息、HTTPRequest跟踪信息、Metrics信息、@RequestMapping路径信息、应用的各种配置信息、程序请求的次数和时间等信息。这里暂时不对具体的端点进行说明,因为不同版本之间存在差异。我们先来看一下打开所有端点然后访问http://localhost:8080/actuator可以看到的端点信息。至于你使用的版本包含了哪些端点,用同样的方法查看。SpringBoot的集成将SpringBootActuator集成到SpringBoot项目中非常方便,只需要在pom文件中添加相应的依赖即可:org.springframework.bootspring-boot-starter-actuator这里是SpringBoot2.2.2.RELEASE版本。启动项目,访问http://localhost:8080/actuator可以看到当前可以访问的端口列表:{"_links":{"self":{"href":"http://localhost:8080/actuator",“templated”:false},“health-path”:{“href”:“http://localhost:8080/actuator/health/{*path}”,“templated”:true},“health”:{“href":"http://localhost:8080/actuator/health","templated":false},"info":{"href":"http://localhost:8080/actuator/info","templated":false}}}可见当前版本默认支持获取self、health-path、health和info端点信息,其他信息不对外开放。此时,如果需要查看上面提到的所有端点,可以在应用配置文件中配置如下:management:endpoints:web:exposure:include:'*'jmx:exposure:include:'*'这是好吧现在查看所有端点。该方法只对SpringBoot2.0之后的版本有效。需要注意的是配置中的*需要加上单引号或者双引号。另外,不推荐这种形式的配置。这将在没有授权验证的情况下将所有端点暴露给外界。推荐的方式是在include中直接指定使用哪些端点。同时,敏感操作也需要鉴权。指定配置的格式如下:management:endpoints:web:exposure:include:health,infojmx:exposure:include:health,info不同的端点可以用英文逗号分隔。其实Endpoint的数据结构在一开始就已经看到了/actuator返回的数据结构,也就是endpoint自身的信息。在/actuator的返回信息中,还可以看到其他可访问端点的地址。例如,在这里访问http://localhost:8080/actuator/health。结构如下:{"status":"UP"}端点返回的结果JSON格式,上面返回的status为UP,代表系统健康运行。当然,对于其他端点的访问,返回的结果基本相同,这里就不一一展示了。停止服务运行在上面的端点中,你会发现服务的端点并没有关闭。是的,默认情况下,即使include设置为“*”,影响服务的操作,如shutdown,仍然是不启用的。对于此类操作,我们首先需要设置为可用:management:endpoint:shutdown:enabled:trueendpoints:web:exposure:include:'*'jmx:exposure:include:'*'此时,访问/actuator看到/shutdown端点对应的路径http://localhost:8080/actuator/shutdown。通过curl命令或postman向端点发送post请求:curl-X"POST""http://localhost:8080/actuator/shutdown"执行后发现服务被关闭。类似停止服务器的操作还有很多,比如重启、暂停、重启等,可以根据具体版本进行配置。当前版本只找到shutdown端点,没有restart、pause、restart端点的配置项。通过上述方式,可以优雅的关闭SpringBoot应用,但是存在很大的安全隐患。如果知道ip和端口号就可以模拟停止服务的请求,所以需要加一些安全限制。management.endpoints.web.base-path自定义关机请求路径;management.server.address设置为本地ip,防止远程访问连接关闭服务;management.server.port自定义关机请求路径端口号;调整最终的配置文件如下:management:endpoint:shutdown:enabled:trueendpoints:web:exposure:include:'*'jmx:exposure:include:'*'server:#Customportport:8080#Remotemanagementconnections不允许,安全考虑地址:127.0.0.1当然,如果这种方式不适合你,你也可以考虑引入spring-boot-starter-security,通过SpringSecurity来保证ActuatorEndpoints的安全。这时候用户名和密码就验证通过了。关于SpringSecurity本文不展开。自定义端点虽然默认端点可以满足大部分需求,但一些特殊需求仍然需要能够支持自定义端点。自定义Endpoint端点,我们只需要在我们新建的Bean上使用@Endpoint注解,Bean中的方法可以通过JMX或者HTTP暴露出来。除此之外,EndPoint也可以使用@JmxEndpoint或@WebEndpoint来编写。但是这些EndPoints受限于它们的暴露方式。例如,@WebEndpoint仅通过HTTP公开,而不是通过JMX公开。那么类中的所有方法都支持publicdisclosure吗?很明显不是。Actuator为方法提供了三种注解。只有具有三个注解的方法才能公开,每个注解都有一个支持它的HTTP方法。@ReadOperation对应HTTPGET请求,@WriteOperation对应HTTPPOST请求,@DeleteOperation对应HTTPDELETE请求。我们来看一个简单的用法示例:@Component@Endpoint(id="my")publicclassEndpointCustom{@ReadOperationpublicStringendpointCustomRead(Stringcontent){return"请求的内容:"+content;}@WriteOperationpublicStringendpointCustomWrite(Stringcontent){return"写入的内容:"+content;}@DeleteOperationpublicStringendpointCustomDelete(Stringcontent){return"删除内容:"+content;}}对应GET请求:curl-XGEThttp://localhost:8080/actuator/my?content=endpointGet执行后会返回信息"请求内容:端点获取”。同样的POST请求是:curl-XPOSThttp://localhost:8080/actuator/my?content=endpointPostDELETE请求是:curl-XDELETEhttp://localhost:8080/actuator/my?content=endpointDELETE以上只是一个简单的自定义示例,根据具体的业务场景,可以定义更丰富的端点实现。小结通过本文,我们了解了SpringBoot集成Actuator的基本操作。集成非常简单,因为SpringBoot已经帮我们完成了大部分的事情,我们只需要有针对性地进行配置即可。对于预定义端点不能满足业务需求的情况,还可以通过定制实现专业化。学习Actuator最重要的一点就是了解它的应用场景。本文完整源码地址:https://github.com/secbr/springboot-all/tree/master/springboot-actuator