Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行状况监控等!

前言

去年咱们项目作了微服务1.0的架构转型,可是服务监控这块却没有跟上。这不,最近我就被分配了要将咱们核心的微服务应用所有监控起来的任务。咱们的微服务应用都是SpringBoot 应用,所以就天然而然的想到了借助Spring Boot 的Actuator 模块。java

本篇是我在完成这个工单以后,对Spring Boot Actuator模块 学习应用的总结。在本篇文章中,你能够学习到:web

一、Spring Boot Actuator 的快速使用入门
二、Spring Boot Actuator 的一些重要的endpoints的介绍
三、如何经过Actuator 模块实时查看当前应用的线程 dump信息
四、如何经过Actuator 模块实时查看当前应用的堆信息
五、如何经过Actuator 模块实时修改当前应用的日志打印等级
六、...redis

以后我还会介绍:spring

TODO:SpringBoot 微服务应用集成Prometheus + Grafana实现监控告警chrome

1、什么是 Spring Boot Actuator

Spring Boot Actuator 模块提供了生产级别的功能,好比健康检查,审计,指标收集,HTTP 跟踪等,帮助咱们监控和管理Spring Boot 应用、Bean加载状况、环境变量、日志信息、线程信息,JVM 堆信息等 。这个模块是一个采集应用内部信息暴露给外部的模块,上述的功能均可以经过HTTP 和 JMX 访问。数据库

由于暴露内部信息的特性,Actuator 也能够和一些外部的应用监控系统整合(Prometheus, Graphite, DataDog, Influx, Wavefront, New Relic等)。这些监控系统提供了出色的仪表板,图形,分析和警报,可帮助你经过一个统一友好的界面,监视和管理你的应用程序。json

Actuator使用Micrometer与这些外部应用程序监视系统集成。这样一来,只需不多的配置便可轻松集成外部的监控系统。浏览器

Micrometer 为 Java 平台上的性能数据收集提供了一个通用的 API,应用程序只须要使用 Micrometer 的通用 API 来收集性能指标便可。Micrometer 会负责完成与不一样监控系统的适配工做。这就使得切换监控系统变得很容易。tomcat

对比 Slf4j 之于 Java Logger 中的定位。安全

2、快速开始,建立一个Spring Boot Actuator Demo

咱们先建立一个demo应用。

你能够经过Spring Boot CLI 建立:

spring init -d=web,actuator -n=actuator-demo actuator-demo

或者经过Spring Initializr 建立:

Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行状况监控等!

对应的maven依赖:

<dependencies>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
...
</dependencies>

对应的Gradle 依赖:

dependencies {
compile("org.springframework.boot:spring-boot-starter-actuator")
}

3、Endpoints 介绍

Spring Boot 提供了所谓的 endpoints (下文翻译为端点)给外部来与应用程序进行访问和交互。

打比方来讲, /health 端点 提供了关于应用健康状况的一些基础信息。metrics 端点提供了一些有用的应用程序指标(JVM 内存使用、系统CPU使用等)。

这些 Actuator 模块原本就有的端点咱们称之为原生端点。根据端点的做用的话,咱们大概能够分为三大类:

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

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

操做控制类:提供了对应用的关闭等操做类功能。

详细的原生端点介绍,请以官网为准,这里就不赘述徒增篇幅。

须要注意的就是:

一、每个端点均可以经过配置来单独禁用或者启动

二、不一样于Actuator 1.x,Actuator 2.x 的大多数端点默认被禁掉。Actuator 2.x 中的默认端点增长了 /actuator前缀。默认暴露的两个端点为 /actuator/health/actuator/info

4、端点暴露配置

咱们能够经过如下配置,来配置经过JMX 和 HTTP 暴露的端点。

Property Default
management.endpoints.jmx.exposure.exclude
management.endpoints.jmx.exposure.include *
management.endpoints.web.exposure.exclude
management.endpoints.web.exposure.include info,healt

能够打开全部的监控点

management.endpoints.web.exposure.include=*

也能够选择打开部分,"*" 表明暴露全部的端点,若是指定多个端点,用","分开

management.endpoints.web.exposure.exclude=beans,trace`

Actuator 默认全部的监控点路径都在 /actuator/*,固然若是有须要这个路径也支持定制。

management.endpoints.web.base-path=/minitor

设置完重启后,再次访问地址就会变成 /minitor/*

如今咱们按照以下配置:

# "*" 表明暴露全部的端点 若是指定多个端点,用","分开
management.endpoints.web.exposure.include=*
# 赋值规则同上
management.endpoints.web.exposure.exclude=

启动DEMO程序,访问 http://localhost:8080/actuator,查看暴露出来的端点:

Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行状况监控等!


上面这样显示是由于chrome 浏览器安装了 JSON-handle 插件,实际上就是返回一大段json

下面,我会着重介绍几个比较重要的端点。

5、重要端点解析

5.1 /health端点

/health端点会聚合你程序的健康指标,来检查程序的健康状况。端点公开的应用健康信息取决于:

management.endpoint.health.show-details=always

该属性可使用如下值之一进行配置:

Name Description
never 不展现详细信息,up或者down的状态,默认配置
when-authorized 详细信息将会展现给经过认证的用户。受权的角色能够经过 management.endpoint.health.roles配置
always 对全部用户暴露详细信息

按照上述配置,配置成 always以后,咱们启动项目,访问 http://localhost:8080/actuator/health端口,能够看到这样的信息:

Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行状况监控等!

是否是感受好像健康信息有点少?先别急,那是由于咱们建立的是一个最基础的Demo项目,没有依赖不少的组件。

/health端点有不少自动配置的健康指示器:如redis、rabbitmq、db等组件。当你的项目有依赖对应组件的时候,这些健康指示器就会被自动装配,继而采集对应的信息。如上面的 diskSpace 节点信息就是 DiskSpaceHealthIndicator 在起做用。

Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行状况监控等!

上述截图取自官方文档

这是我另外一个项目的 /health端点信息。

Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行状况监控等!

当如上的组件有一个状态异常,应用服务的总体状态即为down。咱们也能够经过配置禁用某个组件的健康监测。

management.health.mongo.enabled:  false

或者禁用全部自动配置的健康指示器:

management.health.defaults.enabled:  false

⭐自定义 Health Indicator

固然你也能够自定义一个Health Indicator,只须要实现 HealthIndicator 接口或者继承 AbstractHealthIndicator类。

/**
* @author Richard_yyf
* @version 1.0 2020/1/16
*/
@Component
public  class  CustomHealthIndicator  extends  AbstractHealthIndicator  {
@Override
protected  void doHealthCheck(Health.Builder builder)  throws  Exception  {
// 使用 builder 来建立健康状态信息
// 若是你throw 了一个 exception,那么status 就会被置为DOWN,异常信息会被记录下来
builder.up()
.withDetail("app",  "这个项目很健康")
.withDetail("error",  "Nothing, I'm very good");
}
}

最终效果:

Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行状况监控等!

5.2 /metrics端点

/metrics端点用来返回当前应用的各种重要度量指标,好比:内存信息、线程信息、垃圾回收信息、tomcat、数据库链接池等。

{
"names":  [
"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,返回信息以下:

Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行状况监控等!

你也能够用query param的方式查看单独的一块区域。好比你能够访问 /actuator/metrics/jvm.memory.max?tag=id:Metaspace。结果就是:

Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行状况监控等!

5.3 /loggers端点

/loggers 端点暴露了咱们程序内部配置的全部logger的信息。咱们访问 /actuator/loggers能够看到,

Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行状况监控等!

你也能够经过下述方式访问单独一个logger,

http://localhost:8080/actuator/loggers/{name}

好比我如今访问 root logger, http://localhost:8080/actuator/loggers/root

{
"configuredLevel":  "INFO",
"effectiveLevel":  "INFO"
}

⭐改变运行时的日志等级

/loggers端点我最想提的就是这个功能,可以动态修改你的日志等级。

好比,咱们能够经过下述方式来修改 root logger的日志等级。咱们只须要发起一个URL 为 http://localhost:8080/actuator/loggers/rootPOST请求,POST报文以下:

{
"configuredLevel":  "DEBUG"
}

Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行状况监控等!

仔细想一想,这个功能是否是很是有用。若是在生产环境中,你想要你的应用输出一些Debug信息以便于你诊断一些异常状况,你你只须要按照上述方式就能够修改,而不须要重启应用。

若是想重置成默认值,把value 改为 null

5.4 /info端点

/info端点能够用来展现你程序的信息。我理解过来就是一些程序的基础信息。而且你能够按照本身的需求在配置文件 application.properties中个性化配置(默认状况下,该端点只会返回一个空的json内容。):

info.app.name=actuator-test-demo
info.app.encoding=UTF-8
info.app.java.source=1.8
info.app.java.target=1.8
# 在 maven 项目中你能够直接用下列方式引用 maven properties的值
# 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 /beans端点

/beans端点会返回Spring 容器中全部bean的别名、类型、是否单例、依赖等信息。

访问 http://localhost:8080/actuator/beans,返回以下:

Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行状况监控等!

5.6 /heapdump 端点

访问:http://localhost:8080/actuator/heapdump会自动生成一个 Jvm 的堆文件 heapdump。咱们可使用 JDK 自带的 Jvm 监控工具 VisualVM 打开此文件查看内存快照。

Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行状况监控等!

5.7 /threaddump 端点

这个端点我我的以为特别有用,方便咱们在平常定位问题的时候查看线程的状况。主要展现了线程名、线程ID、线程的状态、是否等待锁资源、线程堆栈等信息。就是可能查看起来不太直观。访问 http://localhost:8080/actuator/threaddump返回以下:

Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行状况监控等!

5.8 /shutdown端点

这个端点属于操做控制类端点,能够优雅关闭 Spring Boot 应用。要使用这个功能首先须要在配置文件中开启:

management.endpoint.shutdown.enabled=true

因为 shutdown 接口默认只支持 POST 请求,咱们启动Demo项目,向 http://localhost:8080/actuator/shutdown发起 POST请求。返回信息:

{
"message":  "Shutting down, bye..."
}

而后应用程序被关闭。

因为开放关闭应用的操做自己是一件很是危险的事,因此真正在线上使用的时候,咱们须要对其加入必定的保护机制,好比:定制Actuator的端点路径、整合Spring Security进行安全校验等。(不是特别必要的话,这个端点不用开)

6、整合Spring Security 对端点进行安全校验

因为端点的信息和产生的交互都是很是敏感的,必须防止未经受权的外部访问。若是您的应用程序中存在Spring Security的依赖,则默认状况下使用基于表单的HTTP身份验证来保护端点。

若是没有,只须要增长对应的依赖便可:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

添加以后,咱们须要定义安全校验规则,来覆盖Spring Security 的默认配置。

这里我给出了两个版本的模板配置:

import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.boot.actuate.context.ShutdownEndpoint;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* @author Richard_yyf
*/
@Configuration
public  class  ActuatorSecurityConfig  extends  WebSecurityConfigurerAdapter  {
/*
* version1:
* 1\. 限制 '/shutdown'端点的访问,只容许ACTUATOR_ADMIN访问
* 2\. 容许外部访问其余的端点
* 3\. 容许外部访问静态资源
* 4\. 容许外部访问 '/'
* 5\. 其余的访问须要被校验
* version2:
* 1\. 限制全部端点的访问,只容许ACTUATOR_ADMIN访问
* 2\. 容许外部访问静态资源
* 3\. 容许外部访问 '/'
* 4\. 其余的访问须要被校验
*/
@Override
protected  void configure(HttpSecurity http)  throws  Exception  {
// 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();
// version2
http
  .authorizeRequests()
.requestMatchers(EndpointRequest.toAnyEndpoint())
.hasRole("ACTUATOR_ADMIN")
.requestMatchers(PathRequest.toStaticResources().atCommonLocations())
.permitAll()
.antMatchers("/")
.permitAll()
.antMatchers("/**")
.authenticated()
.and()
.httpBasic();
}
}

application.properties的相关配置以下:

# Spring Security Default user name and password
spring.security.user.name=actuator
spring.security.user.password=actuator
spring.security.user.roles=ACTUATOR_ADMIN
相关文章
相关标签/搜索