spring-boot-actuator入门实用教程

文章目录

      • 一、概述
      • 二、基本使用
          • 1、添加依赖
          • 2、启动项目,并访问地址 http://localhost:8081/actuator
      • 三、进阶使用
      • 四、自定义 endpoint 和健康状况
          • 1、自定义 endpoint
          • 2、自定义健康状况检查
      • 五、几个实用的 endpoint
          • 1、loggers
          • 2、shutdown

一、概述

spring-boot-actuator 是 spring-boot 周边组件之一,主要是用来查询或监控 spring-boot 项目各种组件、各种维度的度量指标,比如环境变量信息、日志级别、spring bean 信息、组件(redis、mq、db)健康状态等,可以通过 jmx 技术或者 http 技术来使用 actuator,下面主要是通过 http 技术来讲解其使用方法以及自定义 endpoint 端点信息和 health indicator 健康状况指示信息。

二、基本使用

1、添加依赖
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-actuatorartifactId>
    <version>2.3.2.RELEASEversion>
dependency>
2、启动项目,并访问地址 http://localhost:8081/actuator

默认会 expose 两个 web endpoint,分别是 health、info
spring-boot-actuator入门实用教程_第1张图片

打开 http://localhost:8081/actuator/health,看到的响应如下
spring-boot-actuator入门实用教程_第2张图片

说明应用程序是健康的。

在 application.properties 配置文件中添加配置 management.endpoint.health.show-details=always 后再打开该链接,得到的响应如下
spring-boot-actuator入门实用教程_第3张图片

可以看到显示的结果变多了,不仅显示了应用的健康状况,也显示了应用中组件的健康状况,比如我的应用中使用了 nacos 注册中心,响应中就多了个 nacosDiscovery 组件。

三、进阶使用

默认情况下,只暴露了两个端点(info endpoint 和 health endpoint),现在我想暴露全部的端点,只需要在 application.properties 配置文件中加上配置 management.endpoints.web.exposure.include=*,访问 http://localhost:8081/actuator 结果如下

{
    "_links": {
        "self": {
            "href": "http://localhost:8081/actuator",
            "templated": false
        },
        "archaius": {
            "href": "http://localhost:8081/actuator/archaius",
            "templated": false
        },
        "nacosdiscovery": {
            "href": "http://localhost:8081/actuator/nacosdiscovery",
            "templated": false
        },
        "beans": {
            "href": "http://localhost:8081/actuator/beans",
            "templated": false
        },
        "caches-cache": {
            "href": "http://localhost:8081/actuator/caches/{cache}",
            "templated": true
        },
        "caches": {
            "href": "http://localhost:8081/actuator/caches",
            "templated": false
        },
        "health": {
            "href": "http://localhost:8081/actuator/health",
            "templated": false
        },
        "health-path": {
            "href": "http://localhost:8081/actuator/health/{*path}",
            "templated": true
        },
        "info": {
            "href": "http://localhost:8081/actuator/info",
            "templated": false
        },
        "conditions": {
            "href": "http://localhost:8081/actuator/conditions",
            "templated": false
        },
        "configprops": {
            "href": "http://localhost:8081/actuator/configprops",
            "templated": false
        },
        "env-toMatch": {
            "href": "http://localhost:8081/actuator/env/{toMatch}",
            "templated": true
        },
        "env": {
            "href": "http://localhost:8081/actuator/env",
            "templated": false
        },
        "loggers": {
            "href": "http://localhost:8081/actuator/loggers",
            "templated": false
        },
        "loggers-name": {
            "href": "http://localhost:8081/actuator/loggers/{name}",
            "templated": true
        },
        "heapdump": {
            "href": "http://localhost:8081/actuator/heapdump",
            "templated": false
        },
        "threaddump": {
            "href": "http://localhost:8081/actuator/threaddump",
            "templated": false
        },
        "metrics-requiredMetricName": {
            "href": "http://localhost:8081/actuator/metrics/{requiredMetricName}",
            "templated": true
        },
        "metrics": {
            "href": "http://localhost:8081/actuator/metrics",
            "templated": false
        },
        "scheduledtasks": {
            "href": "http://localhost:8081/actuator/scheduledtasks",
            "templated": false
        },
        "mappings": {
            "href": "http://localhost:8081/actuator/mappings",
            "templated": false
        },
        "refresh": {
            "href": "http://localhost:8081/actuator/refresh",
            "templated": false
        },
        "features": {
            "href": "http://localhost:8081/actuator/features",
            "templated": false
        },
        "service-registry": {
            "href": "http://localhost:8081/actuator/service-registry",
            "templated": false
        }
    }
}

可以发现,多了很多个端点,我们重点关注下 metrics 端点,打开浏览器访问 http://localhost:8081/actuator/metrics 得到的结果如下

{
    "names": [
        "http.server.requests",
        "jvm.buffer.count",
        "jvm.buffer.memory.used",
        "jvm.buffer.total.capacity",
        "jvm.classes.loaded",
        "jvm.classes.unloaded",
        "jvm.gc.live.data.size",
        "jvm.gc.max.data.size",
        "jvm.gc.memory.allocated",
        "jvm.gc.memory.promoted",
        "jvm.gc.pause",
        "jvm.memory.committed",
        "jvm.memory.max",
        "jvm.memory.used",
        "jvm.threads.daemon",
        "jvm.threads.live",
        "jvm.threads.peak",
        "jvm.threads.states",
        "logback.events",
        "process.cpu.usage",
        "process.files.max",
        "process.files.open",
        "process.start.time",
        "process.uptime",
        "system.cpu.count",
        "system.cpu.usage",
        "system.load.average.1m",
        "tomcat.sessions.active.current",
        "tomcat.sessions.active.max",
        "tomcat.sessions.alive.max",
        "tomcat.sessions.created",
        "tomcat.sessions.expired",
        "tomcat.sessions.rejected"
    ]
}

可以发现,系统中有这么多可以度量的指标,那么该怎么查看这些指标呢?注意到有个 metrics-requiredMetricName 端点,我们访问这个端点,同时加上指标名称,比如访问 http://localhost:8081/actuator/metrics/jvm.memory.max 来查看 JVM 最大内存,响应结果如下

{
    "name": "jvm.memory.max",
    "description": "The maximum amount of memory in bytes that can be used for memory management",
    "baseUnit": "bytes",
    "measurements": [
        {
            "statistic": "VALUE",
            "value": 5421137919
        }
    ],
    "availableTags": [
        {
            "tag": "area",
            "values": [
                "heap",
                "nonheap"
            ]
        },
        {
            "tag": "id",
            "values": [
                "Compressed Class Space",
                "PS Old Gen",
                "PS Survivor Space",
                "Metaspace",
                "PS Eden Space",
                "Code Cache"
            ]
        }
    ]
}

暴露全部端点的同时,也可以排除某几个指定的端点,比如要排除 env 和 beans 端点,就可以在配置文件中加上 management.endpoints.web.exposure.exclude=env,beans

四、自定义 endpoint 和健康状况

1、自定义 endpoint

自定义 endpoint 时,做好三点即可,一是使该类成为 spring bean,二是加上 @Endpoint 注解,三是灵活运用 @ReadOperation@WriteOperation 注解,自定义的 books endpoint 如下

package org.tunnel.sample.cloud.endpoint;

import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 自定义Endpoint,Endpoint名称为“books”
 *
 * @author debo
 */
@Component
@Endpoint(id = "books")
public class BookEndpoint {

    private List<String> books = Stream.of("java", "c++", "python").collect(Collectors.toList());

    /**
     * 使用GET方法访问,访问链接http://localhost:8081/actuator/books
     * 相当于新增了一个端点,端点名:books
     *
     * @return
     */
    @ReadOperation
    public List<String> books() {
        return books;
    }

    /**
     * 使用GET方法访问,访问链接http://localhost:8081/actuator/books/${bookName}
     * 相当于新增了一个端点,端点名:books-bookName
     *
     * @param bookName
     * @return
     */
    @ReadOperation
    public String bookDesc(@Selector String bookName) {
        if ("java".equals(bookName)) {
            return "Java是世界上最好的语言";
        }
        return "你是谁?";
    }

    /**
     * 使用POST JSON方法访问
     * curl -X POST -H "Content-Type: application/json" http://localhost:8081/actuator/books -d '{"bookName":"钢铁是怎样炼成的","version":3}'
     *
     * @param bookName
     * @param version
     * @return
     */
    @WriteOperation
    public String addBook(String bookName, Integer version) {
        books.add(bookName + version);
        return "成功";
    }
}

启动项目后,会发现 actuator 主页新增两个 endpoint:books 和 books-bookName,其中 books 端点同时支持 GET 和 POST 请求,POST 请求是由 @WriteOperation 注解支持,books-bookName 端点支持 GET 请求,参数由 path 路径传入

spring-boot-actuator入门实用教程_第4张图片

注意:需要在 maven-complier-plugin 插件配置 -parameters 编译参数,否则端点名称不会是 books-bookName,而是 books-arg0。

2、自定义健康状况检查

自定义健康状况检查时,做好两点即可,一是使该类成为 spring bean,二是继承 AbstractHealthIndicator 类,实现 doHealthCheck 方法

package org.tunnel.sample.cloud.endpoint.health;

import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health.Builder;
import org.springframework.stereotype.Component;

/**
 * 自定义健康状态检查,如果beanName是myHealthIndicator,那么在health中出现的标识就是“my”
 *
 * @author debo
 * @date 2022-01-26
 */
@Component
public class MyHealthIndicator extends AbstractHealthIndicator {
    @Override
    protected void doHealthCheck(Builder builder) throws Exception {
        builder.up();
    }
}

打开 http://localhost:8081/actuator/health,发现多了个 my 健康状况检查标识
spring-boot-actuator入门实用教程_第5张图片

五、几个实用的 endpoint

1、loggers

通过 loggers 端点,可以动态修改项目的日志级别,比如想要修改 ROOT logger 的日志级别,就可以发送 POST 请求 curl -X POST -H "Content-Type: application/json" http://localhost:8081/actuator/loggers/ROOT -d '{"configuredLevel":"DEBUG"}'

2、shutdown

shutdown 端点可以用来远程关闭 spring-boot 应用,比如发送 POST 请求 curl -X POST http://localhost:8081/actuator/shutdown 即可关闭应用。

默认情况下,除了 shutdown endpoint ,其它所有的 endpoint 都是开启(enable)的,也就是说,shutdown endpoint 被 expose 后,还需要手动 enable 才能生效,enable 的格式如 management.endpoint..enabled ,比如要开启 shutdown endpoint ,需要在配置文件 application.properties 中添加配置 management.endpoint.shutdown.enabled=true

你可能感兴趣的:(spring-boot,spring,boot,actuator,metrics)