乐趣区

关于java:Spring-Boot-Actuator-健康检查度量指标收集监控一文搞定

作者:Richard_Yi

原文:https://juejin.im/post/684490…

前言

去年咱们我的项目做了微服务 1.0 的架构转型,然而服务监控这块却没有跟上。这不,最近我就被调配了要将咱们外围的微服务利用全副监控起来的工作。咱们的微服务利用都是 SpringBoot 利用,因而就自然而然的想到了借助 Spring Boot 的 Actuator 模块。(没吃过猪肉总听过猪叫见过猪跑吧🤪)。

本篇是我在实现这个工单之后,对 Spring Boot Actuator 模块 学习利用的总结。在本篇文章中,你能够学习到:

  • Spring Boot Actuator 的疾速应用入门
  • Spring Boot Actuator 的一些重要的 endpoints 的介绍
  • 如何通过 Actuator 模块实时查看以后利用的线程 dump 信息
  • 如何通过 Actuator 模块实时查看以后利用的堆信息
  • 如何通过 Actuator 模块实时批改以后利用的日志打印等级

之后我还会介绍:

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

一、什么是 Spring Boot Actuator

Spring Boot Actuator 模块提供了生产级别的性能,比方健康检查,审计,指标收集,HTTP 跟踪等,帮忙咱们监控和治理 Spring Boot 利用。这个模块是一个采集利用外部信息裸露给内部的模块,上述的性能都能够通过 HTTP 和 JMX 拜访。

因为裸露外部信息的个性,Actuator 也能够和一些内部的利用监控零碎整合(Prometheus, Graphite, DataDog, Influx, Wavefront, New Relic 等)。这些监控零碎提供了杰出的仪表板,图形,剖析和警报,可帮忙你通过一个对立敌对的界面,监督和治理你的应用程序。

Actuator 应用 Micrometer 与这些内部应用程序监督系统集成。这样一来,只需很少的配置即可轻松集成内部的监控零碎。

Micrometer 为 Java 平台上的性能数据收集提供了一个通用的 API,应用程序只须要应用 Micrometer 的通用 API 来收集性能指标即可。Micrometer 会负责实现与不同监控零碎的适配工作。这就使得切换监控零碎变得很容易。

比照 Slf4j 之于 Java Logger 中的定位。

二、疾速开始,创立一个 Spring Boot Actuator Demo

咱们先创立一个 demo 利用。

  • 你能够通过 Spring Boot CLI 创立:
spring init -d=web,actuator -n=actuator-demo actuator-demo
复制代码
  • 或者通过 Spring Initializr 创立:

  • 对应的 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")
}

三、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

四、端点裸露配置

咱们能够通过以下配置,来配置通过 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,查看裸露进去的端点:


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

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

五、重要端点解析

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 端口,能够看到这样的信息:

是不是感觉如同衰弱信息有点少?先别急,那是因为咱们创立的是一个最根底的 Demo 我的项目,没有依赖很多的组件。

/health端点有很多主动配置的衰弱指示器:如 redis、rabbitmq、db 等组件。当你的我的项目有依赖对应组件的时候,这些衰弱指示器就会被主动拆卸,继而采集对应的信息。如下面的 diskSpace 节点信息就是DiskSpaceHealthIndicator 在起作用。

上述截图取自官网文档

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

当如上的组件有一个状态异样,应用服务的整体状态即为 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 */@Componentpublic 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");    }}

最终成果:

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,返回信息如下:

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

5.3/loggers端点

/loggers 端点裸露了咱们程序外部配置的所有 logger 的信息。咱们拜访 /actuator/loggers 能够看到,

你也能够通过下述形式拜访独自一个 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"}

认真想想,这个性能是不是十分有用。如果在生产环境中,你想要你的利用输入一些 Debug 信息以便于你诊断一些异常情况,你你只须要依照上述形式就能够批改,而不须要重启利用。

如果想重置成默认值,把 value 改成 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 我的项目中你能够间接用下列形式援用 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,返回如下:

5.6 /heapdump 端点

拜访:http://localhost:8080/actuator/heapdump会主动生成一个 Jvm 的堆文件 heapdump。咱们能够应用 JDK 自带的 Jvm 监控工具 VisualVM 关上此文件查看内存快照。

5.7 /threaddump 端点

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

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 进行平安校验 等。(不是特地必要的话,这个端点不必开)

六、整合 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

结语

本篇文章内容就到这里。

对应的源码能够 Github 上看到。(https://github.com/Richard-yy…)

如果本文有帮忙到你,心愿能点个赞,这是对我的最大能源🤝🤝🤗🤗。

参考:

https://docs.spring.io/spring…

http://www.ityouknow.com/spri…

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿(2021 最新版)

2. 别在再满屏的 if/ else 了,试试策略模式,真香!!

3. 卧槽!Java 中的 xx ≠ null 是什么新语法?

4.Spring Boot 2.5 重磅公布,光明模式太炸了!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

退出移动版