当前位置: 首页 > 科技观察

SpringBoot健康检查、指标、监控,一文搞定!

时间:2023-03-11 23:28:14 科技观察

前言去年我们的项目进行了微服务1.0架构改造,但是服务监控没有跟上。不,最近我被分配了监控我们所有核心微服务应用程序的任务。我们的微服务应用都是SpringBoot应用,那么很自然的就会想到带有SpringBoot的Actuator模块。(我没吃过猪肉,但我听过猪叫,见过猪逃跑……)。这篇文章是我在完成本次工单后对SpringBootActuator模块的学习和应用的总结。在本文中,您可以了解到:SpringBootActuator快速入门SpringBootActuator一些重要端点的介绍如何通过Actuator模块实时查看当前应用的threaddump信息如何查看当前的heap通过Actuator模块实时应用如何通过Actuator模块实时修改当前应用的日志打印级别...后面会介绍:TODO:SpringBoot微服务应用集成Prometheus+Grafana实现监控告警1.什么是SpringBootActuatorSpringBootActuator模块提供了生产级的特性,比如健康检查、审计、指标收集、HTTP跟踪等,帮助我们监控和管理SpringBoot应用。该模块是收集应用程序内部信息并对外暴露的模块。可以通过HTTP和JMX访问以上功能。由于暴露内部信息的性质,Actuator还可以与一些外部应用程序监控系统(Prometheus、Graphite、DataDog、Influx、Wavefront、NewRelic等)集成。这些监控系统提供出色的仪表板、图表、分析和警报,可帮助您通过统一友好的界面监控和管理您的应用程序。Actuator使用Micrometer与这些外部应用程序监控系统集成。这使得以最少的配置集成外部监控系统变得容易。Micrometer在Java平台上提供了通用的性能数据采集API,应用程序只需要使用Micrometer的通用API即可采集性能指标。Micrometer将负责完成与不同监控系统的适配工作。这使得切换监控系统变得容易。比较Slf4j在JavaLogger中的定位。2.快速入门,创建一个SpringBootActuatorDemo我们先来创建一个demo应用。我不会介绍SpringBoot的基础知识。我推荐这个实用教程:https://github.com/javastacks/spring-boot-best-practice你可以通过SpringBootCLI创建它:springinit-d=web,actuator-n=actuator-demoactuator-demo复制代码或者通过SpringInitializr创建:对应的maven依赖:...org.springframework.bootspring-boot-starter-actuator...对应的Gradle依赖:dependencies{compile("org.springframework.boot:spring-boot-starter-actuator")}3.Endpoints介绍SpringBoot提供了所谓的endpoints(下面翻译为endpoint))到外部世界以访问应用程序并与之交互。例如,/health端点提供有关应用程序健康状况的一些基本信息。指标端点提供了一些有用的应用程序指标(JVM内存使用情况、系统CPU使用情况等)。这些Actuator模块已经拥有的端点称为本机端点。根据端点的功能,我们大致可以将其分为三类:应用配置类:获取应用中加载的应用配置、环境变量、自动配置报告等与SpringBoot应用密切相关的配置信息。Metrics类:获取应用运行过程中用于监控的指标,如:内存信息、线程池信息、HTTP请求统计等。操作控制类:提供关闭应用等操作功能。关于nativeendpoints的详细介绍请参考官网,这里不再赘述,增加篇幅。注意:每个端点都可以通过配置单独禁用或启用与Actuator1.x不同,Actuator2.x中的大多数端点默认情况下都是禁用的。Actuator2.x中的默认端点添加了/actuator前缀。默认暴露的两个端点是/actuator/health和/actuator/info4.端点暴露配置我们可以通过以下配置来配置通过JMX和HTTP暴露的端点。属性默认management.endpoints.jmx.exposure.excludemanagement.endpoints.jmx.exposure.include*management.endpoints.web.exposure.excludemanagement.endpoints.web.exposure.includeinfo,health可以开启所有监控点:management。endpoints.web.exposure.include=*也可以选择打开部分,“*”表示暴露所有端点,如果指定多个端点,用“,”分隔。management.endpoints.web.exposure.exclude=beans,traceActuator默认所有监控点路径都在/actuator/*。当然,如果有需要,这个路径也支持自定义。设置management.endpoints.web.base-path=/minitor后重启,访问地址又会变成/minitor/*。现在我们配置如下:#"*"表示暴露所有端点。如果指定多个端点,用“,”隔开/localhost:8080/actuator,查看暴露的端点:上面显示是因为chrome浏览器安装了json-handle插件,实际上返回了一大段json。下面,我将重点介绍几个更重要的端点。5.重要端点分析5.1/health端点/health端点会聚合你程序的健康指标来检查程序的健康状况。端点暴露的应用程序健康信息取决于:management.endpoint.health.show-details=always该属性可以配置为以下值之一:名称描述never不显示详细信息,up或down状态,默认configurationiswhen-authorized详细信息将显示给经过身份验证的用户。可以通过management.endpoint.health.roles配置授权角色,以始终向所有用户公开详细信息。按照上面的配置,配置always之后,我们启动项目,访问http://localhost:8080/actuator/health端口,可以看到这样的信息:是不是感觉健康信息少了点?不用担心,这是因为我们创建了一个基本的Demo工程,没有依赖很多组件。为你分享SpringBoot学习笔记。/health端点有很多自动配置的健康指标:redis、rabbitmq、db等组件。当你的项目依赖了相应的组件时,会自动组装这些健康指标,然后收集相应的信息。比如上面的diskSpace节点信息就是DiskSpaceHealthIndicator在起作用。以上截图来自官方文档这是我另一个项目的/health端点信息。当上述其中一个组件状态异常时,应用服务整体状态为down。我们也可以通过配置来关闭组件的健康监控。management.health.mongo.enabled:false或禁用所有自动配置的健康指标:management.health.defaults.enabled:false?CustomHealthIndicator当然你也可以自定义一个HealthIndicator,只需要实现HealthIndicator接口或者继承AbstractHealthIndicator班级。/***@authorRichard_yyf*@version1.02020/1/16*/@ComponentpublicclassCustomHealthIndicatorextendsAbstractHealthIndicator{@OverrideprotectedvoiddoHealthCheck(Health.Builderbuilder)throwsException{//使用builder创建健康状态信息//如果抛出异常,那么status会是设置为DOWN,会记录异常信息作用:5.2/metrics端点/metrics端点用于返回当前应用的各种重要指标,如:内存信息、线程信息、垃圾回收信息、tomcat、数据库连接池等。{“名称”:[“tomcat.threads.busy”,“jvm.threads.states”,“jdbc.connections.active”,“jvm.gc.memory.promoted”,“http.server.requests”,“hikaricp.connections.max","hikaricp.connections.min","jvm.memory.used","jvm.gc.max.data.size","jdbc.connections.max",....]}是不同的从1.x开始,Actuator在这个界面看不到具体的指标信息,只能展示指标列表。为了获取某个指标的详细信息,我们可以请求具体的指标信息,像这样:http://localhost:8080/actuator/metrics/{MetricName}比如我访问/actuator/metrics/jvm。memory.max,返回信息如下:也可以使用queryparam查看单个区域。例如,您可以访问/actuator/metrics/jvm.memory.max?tag=id:Metaspace。结果是:5.3/loggers端点/loggers端点公开了我们程序中配置的所有记录器的信息。我们可以通过访问/actuator/loggers来查看。也可以通过以下方式访问单个logger,http://localhost:8080/actuator/loggers/{name}比如我现在访问的是rootlogger,http://localhost:8080/actuator/loggers/root{"configuredLevel":"INFO","effectiveLevel":"INFO"}?在运行时更改日志级别/记录器端点。最想说的就是这个功能,可以动态修改你的日志级别。例如,我们可以通过以下方式修改rootlogger的日志级别。我们只需要发起一个POST请求,URL为http://localhost:8080/actuator/loggers/root,POST消息如下:{"configuredLevel":"DEBUG"}仔细想想,这个功能是不是很有用?如果在生产环境中,想让你的应用输出一些Debug信息,以便诊断一些异常情况,只需要按照上面的方法修改即可,不需要重启应用。如果要重置为默认值,请将值更改为null。5.4/info端点/info端点可用于显示有关程序的信息。我了解的是一些程序的基本信息。并且可以根据自己的需要在配置文件application.properties中进行个性化配置(默认情况下端点只会返回一个空的json内容。):info.app.name=actuator-test-demoinfo.app.encoding=UTF-8info.app.java.source=1.8info.app.java.target=1.8#在maven项目中可以直接引用通过以下方式mavenproperties#info.app.encoding=@project.build.sourceEncoding@#info.app.java.source=@java.version@#info.app.java.target=@java.version@的值启动项目,访问http://localhost:8080/actuator/info:{"app":{"encoding":"UTF-8","java":{"source":"1.8.0_131","target":"1.8.0_131"},"name":"actuator-test-demo"}}5.5/beansendpoint/beansendpoint会返回Spring容器中所有bean的别名、类型、单例、依赖等信息。访问http://localhost:8080/actuator/beans,返回如下:5.6/heapdump端点访问:http://localhost:8080/actuator/heapdump会自动生成一个Jvm堆文件heapdump。我们可以使用JDK自带的Jvm监控工具VisualVM打开这个文件查看内存快照。5.7/threaddump端点个人觉得这个端点很好用,方便我们每天定位问题的时候查看线程情况。主要显示线程名称、线程ID、线程状态、是否等待锁资源、线程堆栈等信息,可能看起来不够直观。访问http://localhost:8080/actuator/threaddump,返回如下:5.8/shutdownendpoint该端点属于操作控制端点,可以优雅的关闭SpringBoot应用。要使用该功能,首先需要在配置文件中开启:management.endpoint.shutdown.enabled=true由于关闭界面默认只支持POST请求,所以我们启动Demo工程,向http://发起POST请求/localhost:8080/执行器/关机。返回消息:{"message":"Shuttingdown,bye..."}应用关闭。由于打开和关闭应用程序本身的操作是一件非常危险的事情,所以在实际在线使用时,我们需要为其添加一定的保护机制,例如:自定义Actuator的端点路径,集成SpringSecurity进行安全验证,等(如果不是特别需要,这个端点不需要开启)6.集成SpringSecurity,对端点进行安全验证由于端点产生的信息和交互非常敏感,所以必须防止未经授权的外部访问.如果您的应用程序依赖于SpringSecurity,则默认情况下使用基于表单的HTTP身份验证来保护端点。如果没有,只需要添加对应的依赖即可:规则来覆盖SpringSecurity的默认配置。这里我给出两个版本的模板配置:importorg.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;importorg.springframework.boot.actuate.context.ShutdownEndpoint;导入org.springframework.boot.autoconfigure.security。servlet.PathRequest;importorg.springframework.context.annotation.Configuration;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;/***@authorRichard_yyf*/@ConfigurationpublicclassActuatorSecurityConfigextendsWebSecurityConfigurerAdapter{/**version1:*1。限制对“/shutdown”端点的访问,只允许ACTUATOR_ADMIN访问*2。允许外部访问其他端点*3。允许外部访问静态资源*4。允许外部访问'/'*5。其他访问需要验证*version2:*1。限制对所有端点的访问,只允许ACTUATOR_ADMIN访问*2。允许外部访问静态资源*3。允许外部访问'/'*4。其他访问需要验证*/@Overrideprotectedvoidconfigure(HttpSecurityhttp)throwsException{//version1//http//.authorizeRequests()//.requestMatchers(EndpointRequest.to(ShutdownEndpoint.class))//.hasRole("ACTUATOR_ADMIN")//.requestMatchers(EndpointRequest.toAnyEndpoint())//.permitAll()//.requestMatchers(PathRequest.toStaticResources().atCommonLocations())//.permitAll()//.antMatchers("/")//.permitAll()//.antMatchers("/**")//.authenticated()//.and()//.httpBasic();//version2http.authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ACTUATOR_ADMIN").requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll().antMatchers("/").permitAll().antMatchers("/**").authenticated().and().httpBasic();}}application.properties的相关配置如下:#SpringSecurityDefaultusernameandpasswordspring.security.user.name=actuatorspring.security.user.password=actuatorspring.security.user.roles=ACTUATOR_ADMINConclusion的内容本文转至此处,Github上可以看到相应的源码。(https://github.com/Richard-yyf/springboot-actuator-prometheus-test)