Spring Boot应用的健康监控

本文首发于我的网站:Spring Boot应用的健康监控html

在以前的系列文章中咱们学习了如何进行Spring Boot应用的功能开发,以及如何写单元测试、集成测试等,然而,在实际的软件开发中须要作的不只如此:还包括对应用程序的监控和管理。java

正如飞行员不喜欢盲目飞行,程序员也须要实时看到本身的应用目前的运行状况。若是给定一个具体的时间,咱们但愿知道此时CPU的利用率、内存的利用率、数据库链接是否正常以及在给定时间段内有多少客户请求等指标;不只如此,咱们但愿经过图表、控制面板来展现上述信息。最重要的是:老板和业务人员但愿看到的是图表,这些比较直观易懂。程序员

首先,这篇文章讲介绍如何定制本身的health indicator。web

实战

  • 在pom文件中添加spring-boot-starter-actuator依赖
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  • spring-boot-starter-actuator这个库让咱们能够访问应用的不少信息,包括:/env、/info、/metrics、/health等。如今运行程序,而后在浏览器中访问:http://localhost:8080/health,将能够看到下列内容。acatuator库提供监控信息
  • 除了/health能够访问,其余的Endpoints也能够访问,例如/info:首先在application.properties文件中添加对应的属性值,符号*@*包围的属性值来自pom.xml文件中的元素节点。
info.build.artifact=@project.artifactId@
info.build.name=@project.name@
info.build.description=@project.description@
info.build.version=@project.version@
  • 要获取配置文件中的节点值,须要在pom文件中进行必定的配置,首先在<build>节点里面添加:
<resources>
   <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
   </resource>
</resources>

而后在<plugins>节点里面增长对应的插件:面试

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-resources-plugin</artifactId>
   <version>2.6</version>
   <configuration>
      <delimiters>
         <delimiter>@</delimiter>
      </delimiters>
      <useDefaultDelimiters>false</useDefaultDelimiters>
   </configuration>
</plugin>
  • 而后运行应用程序,访问http://localhost:8080/info,能够看到下列信息 http://localhost:8080/info
  • 除了使用系统默认的监控信息,咱们还能够定义本身的health indicator。使用Spring Boot:定制本身的starter一文中作过的db-count-starter做为观察对象,咱们但愿监控每一个数据库接口的运行情况:若是某个接口返回的个数大于等于0,则表示系统正常,表示为UP状态;不然,可能该接口发生异常,表示为DOWN状态。首先,将DbCountRunner类中的getRepositoryName方法由private转为protected,而后在db-count-starter这个模块中也添加actuator依赖。
  • db-count-starter/src/main/com/test/bookpubstarter目录下建立DbCountHealthIndicator.java文件
public class DbCountHealthIndicator implements HealthIndicator {
    private CrudRepository crudRepository;
    public DbCountHealthIndicator(CrudRepository crudRepository) {
        this.crudRepository = crudRepository;
    }
    @Override
    public Health health() {
        try {
            long count = crudRepository.count();
            if (count >= 0) {
                return Health.up().withDetail("count", count).build();
            } else {
                return Health.unknown().withDetail("count", count).build();
            }
        } catch (Exception e) {
            return Health.down(e).build();
        }
    }
}
  • 最后,还须要注册刚刚建立的健康监控器,在DbCountAutoConfiguration.java中增长以下定义:
@Autowired
private HealthAggregator healthAggregator;
@Bean
public HealthIndicator dbCountHealthIndicator(Collection<CrudRepository> repositories) {
    CompositeHealthIndicator compositeHealthIndicator = new
            CompositeHealthIndicator(healthAggregator);
    for (CrudRepository repository: repositories) {
        String name = DbCountRunner.getRepositoryName(repository.getClass());
        compositeHealthIndicator.addHealthIndicator(name, new DbCountHealthIndicator(repository));
    }
    return compositeHealthIndicator;
}

自定义的health indicator

分析

Spring Boot Autuator这个库包括不少自动配置,对外开放了不少endpoints,经过这些endpoints能够访问应用的运行时状态:spring

  • /env提供应用程序的环境变量,若是你在调试时想知道某个配置项在运行时的值,能够经过这个endpoint访问——访问http://localhost:8080/env,能够看到不少方面的配置,例如,class path resources—[tomcat.https.properties]、applicationConfig—[classpath:/application.properties]、commonsConfig、systemEnvironment、systemProperties等。 这些变量的值由Environment实例中的PropertySource实例保存,根据这些属性值所在的层次,有可能在运行时已经作了值替换,跟配置文件中的不同了。为了确认某个属性的具体值,例如book.count.rate属性,能够访问http://localhost:8080/env/book.counter.rate来查询,若是跟配置文件中的不同,则多是被系统变量或者命令行参数覆盖了。EnvironmentEndpoint类负责实现上述功能,有兴趣能够再看看它的源码;
  • /configprops提供不一样配置对象,例如WebConfiguration.TomcatSslConnectionProperties,它与/env不一样的地方在于它会表示出与配置项绑定的对象。尝试下访问http://localhost:8080/configprops,而后在网页中查询custom.tomcat.https,能够看到咱们以前用于配置TomcatSslConnector对象的属性值(参见:让你的Spring Boot工程支持HTTP和HTTPS)。 TomcatSslConnector对应的属性值
  • /autoconfig以web形式对外暴露AutoConfiguration 信息,这些信息的解释能够参考Spring Boot:定制本身的starter一文,这样咱们就不须要经过“修改应用程序的日志级别和查看应用的启动信息”来查看应用的自动配置状况了。
  • /beans,这个endpoint列出全部由Spring Boot建立的bean。 /beans显示全部Spring Boot建立的bean
  • /mapping,这个endpoint显示当前应用支持的URL映射,该映射关系由HandlerMapping类维护,经过这个endpoint能够查询某个URL的路由信息。 /mappings查看URL映射
  • /info,这个endpoint显示应用程序的基本描述,在以前的实践例子中咱们看过它的返回信息,属性值来自appliaction.properties,同时也可使用占位符获取pom.xml文件中的信息。任何以info.开头的属性都会在访问http://localhost:8080/info时显示。
  • /health提供应用程序的健康状态,或者是某个核心模块的健康状态。
  • /metrics,这个endpoint显示Metrics 子系统管理的信息,后面的文章会详细介绍它。

上述各个endpoint是Spring Boot Actuator提供的接口和方法,接下来看看咱们本身定制的HealthIndicator,咱们只须要实现HealthIndicator接口,Spring Boot会收集该接口的实现,并加入到*/health*这个endpoint中。数据库

在咱们的例子中,咱们为每一个CrudRepository实例都建立了一个HealthIndicator实例,为此咱们建立了一个CompositeHealthIndicator实例,由这个实例管理全部的DbHealthIndicator实例。做为一个composite,它会提供一个内部的层次关系,从而能够返回JSON格式的数据。apache

代码中的HealthAggregator实例的做用是:它维护一个map,告诉CompositeHealthIndicator如何决定全部HealthIndicator表明的总体的状态。例如,除了一个repository返回DOWN其余的都返回UP,这时候这个composite indicator做为一个总体应该返回UP仍是DOWN,HealthAggregator实例的做用就在这里。后端

Spring Boot使用的默认的HealthAggregator实现是OrderedHealthAggregator,它的策略是手机全部的内部状态,而后选出在DOWN、OUT_OF_SERVICE、UP和UNKNOWN中间具备最低优先级的那个状态。这里使用策略设计模式,所以具体的状态断定策略能够改变和定制,例如咱们能够建立定制的HealthAggregator设计模式

最后须要考虑下安全问题,经过这些endpoints暴露出不少应用的信息,固然,Spring Boot也提供了配置项,能够关闭指定的endpoint——在application.properties中配置*<name>.enable=false*;

还能够经过设置management.port=-1关闭endpoint的HTTP访问接口,或者是设置其余的端口,供内部的admin服务访问;除了控制端口,还能够设置仅仅让本地访问,只须要设置management.address=127.0.0.1;经过设置management.context-path=/admin,能够设置指定的根路径。综合下,通过上述设置,在本地访问http://127.0.0.1/admin/health来访问健康状态。

能够在防火墙上屏蔽掉不是/admin/*的endpoints访问请求,更进一步,利用Spring Security能够配置验证信息,这样要访问当前应用的endpoints必须使用用户名和密码登录。

参考资料

  1. Endpoints
  2. Complete Guide for Spring Boot Actuator

Spring Boot 1.x系列

  1. Spring Boot的自动配置、Command-line-Runner
  2. 了解Spring Boot的自动配置
  3. Spring Boot的@PropertySource注解在整合Redis中的使用
  4. Spring Boot项目中如何定制HTTP消息转换器
  5. Spring Boot整合Mongodb提供Restful接口
  6. Spring中bean的scope
  7. Spring Boot项目中使用事件派发器模式
  8. Spring Boot提供RESTful接口时的错误处理实践
  9. Spring Boot实战之定制本身的starter
  10. Spring Boot项目如何同时支持HTTP和HTTPS协议
  11. 自定义的Spring Boot starter如何设置自动配置注解
  12. Spring Boot项目中使用Mockito
  13. 在Spring Boot项目中使用Spock测试框架
  14. Spring Boot项目中如何定制拦截器
  15. Spring Boot项目中如何定制PropertyEditors
  16. Spring Boot构建的Web项目如何在服务端校验表单输入

本号专一于后端技术、JVM问题排查和优化、Java面试题、我的成长和自我管理等主题,为读者提供一线开发者的工做和成长经验,期待你能在这里有所收获。javaadu

相关文章
相关标签/搜索