SpringBoot 2.0 + Actuator 应用健康监控管理

springboot的Actuator提供了运行状态监控的功能,可以通过REST、远程Shell和JMX方式来查看。

 

引入Actuator

添加jar包依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- SpringBoot 2.0.3 -->

添加配置信息

# 访问: localhost:8081/monitor/{name}
management:
  # actuator端口
  server:
    port: 8081
  endpoints:
    web:
      # 修改访问路径,2.0之前默认是/,2.0默认是/actuator
      base-path: /monitor
      # 开放所有页面节点 ,默认只开启了health、info两个节点
      exposure:
        include: "*"
  endpoint:
    health:
      # 显示健康具体信息,默认不会显示详细信息
      show-details: always

访问: http://localhost:8081/monitor 获取所有的健康监控接口地址

 

自定义api的访问路径

management:
  endpoints:
    web:
      path-mapping:
        health: /sys-health
        info: /sys-info

 

自定义info接口信息

info:
  name:
    '@project.name@'
  encoding:
    '@project.build.sourceEncoding@'
  description:
    '@project.description@'
  version:
    '@java.version@'

访问: http://localhost:8310/actuator/info

pom文件中需添加如下依赖, 否则application.yaml使用**@XXX@**是无法获取pom中变量值的

<build>
    <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>
    </plugins>
</build>

 

自定义端点

自定义健康监测的端点

在原来内置的端点进行添加,访问的路径还是内置的路径

// 这里的name 就是默认健康节点的名称了
@Component("jaemon")
public class CustomHealthIndicator extends AbstractHealthIndicator {
    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        builder
                // 设置健康信息
                .withDetail("name", "jaemon")
                .withDetail("version", "1.0.0")
                .up().build();
    }
}

访问: http://localhost:8310/actuator/health

自定义健康端点方式

  • 继承AbstractHealthIndicator类
  • 实现 HealthIndicator接口

自定义全新端点

@Endpoint(id = "custom-endpoint")
@Configuration
public class CustomEndpoint {
    /** 计算单位换算类型 */
    private static final Map<String, Long> UNIT_TYPE = Maps.newHashMap();
    static {
        UNIT_TYPE.put("K", 1024L);
        UNIT_TYPE.put("M", 1024 * 1024L);
        UNIT_TYPE.put("G", 1024 * 1024 * 1024L);
    }

    @ReadOperation
    public Map<String, Object> endpoint() {
        Map<String, Object> map = Maps.newHashMap();

        MemoryMXBean memorymbean = ManagementFactory.getMemoryMXBean();
        map.put("堆内存", memorymbean.getHeapMemoryUsage());
        map.put("方法区内存", memorymbean.getNonHeapMemoryUsage());

        List<String> inputArgs = ManagementFactory.getRuntimeMXBean().getInputArguments();
        map.put("运行时设置的JVM参数", inputArgs);

        // 总的内存量
        long totle = Runtime.getRuntime().totalMemory();
        // 空闲的内存量
        long free = Runtime.getRuntime().freeMemory();
        // 最大的内存量
        long max = Runtime.getRuntime().maxMemory();
        Map<String, Long> params = ImmutableMap.of(
                "totalMemory", totle,
                "freeMemory", free,
                "maxMemory", max
        );

        map.put("运行时内存情况", params);

        return map;
    }

    /**
     * @Selector 会将路径上的参数作为变量传递给操作方法
     *
     * init约等于xms的值,max约等于xmx的值。used是已经被使用的内存大小,committed是当前可使用的内存大小(包括已使用的),committed >= used。committed不足时jvm向系统申请,若超过max则发生OutOfMemoryError错误
     */
    @ReadOperation
    public Map<String, Object> select(@Selector String unitType) {
        long conversion = UNIT_TYPE.getOrDefault(unitType.toUpperCase(), 1L);
        Map<String, Object> map = Maps.newHashMap();

        // 堆内存
        MemoryMXBean memorymbean = ManagementFactory.getMemoryMXBean();

        // 方法区内存
        MemoryUsage heapMemoryUsage = memorymbean.getHeapMemoryUsage();
        long heapInit = heapMemoryUsage.getInit() / conversion;
        long heapCommitted = heapMemoryUsage.getCommitted() / conversion;
        long heapUsed = heapMemoryUsage.getUsed() / conversion;
        long heapMax = heapMemoryUsage.getMax() / conversion;

        Map<String, Long> heapMap = Maps.newHashMap();
        heapMap.put("init", heapInit);
        heapMap.put("committed", heapCommitted);
        heapMap.put("used", heapUsed);
        heapMap.put("max", heapMax);
        map.put("堆内存", heapMap);

        MemoryUsage nonHeapMemoryUsage = memorymbean.getNonHeapMemoryUsage();
        long noHeapInit = nonHeapMemoryUsage.getInit() / conversion;
        long noHeapCommitted = nonHeapMemoryUsage.getCommitted() / conversion;
        long noHeapUsed = nonHeapMemoryUsage.getUsed() / conversion;
        long noHeapMax = nonHeapMemoryUsage.getMax() / conversion;

        Map<String, Long> noHeapMap = Maps.newHashMap();
        noHeapMap.put("init", noHeapInit);
        noHeapMap.put("committed", noHeapCommitted);
        noHeapMap.put("used", noHeapUsed);
        noHeapMap.put("max", noHeapMax);
        map.put("方法区内存", noHeapMap);

        List<String> inputArgs = ManagementFactory.getRuntimeMXBean().getInputArguments();
        map.put("运行时设置的JVM参数", inputArgs);

        // 总的内存量
        long totle = Runtime.getRuntime().totalMemory();
        // 空闲的内存量
        long free = Runtime.getRuntime().freeMemory();
        // 最大的内存量
        long max = Runtime.getRuntime().maxMemory();
        Map<String, Long> params = ImmutableMap.of(
                "totalMemory", totle / conversion,
                "freeMemory", free / conversion,
                "maxMemory", max / conversion
        );

        map.put("运行时内存情况", params);

        return map;
    }
}

访问地址:

http://localhost:8310/actuator/custom-endpoint

http://localhost:8310/actuator/custom-endpoint/{unitType}

注意

  • @EndPoint中的id不能使用驼峰法,需要以-分割
  • @Spring Boot会去扫描@EndPoint注解下的@ReadOperation, @WriteOperation, @DeleteOperation注解,分别对应生成Get/Post/Delete的Mapping。注解中有个produces参数,可以指定media type, 如:application/json等

 

metrics接口指标说明

JVM指标

参数 参数说明 是否监控 监控手段 重要度
jvm.memory.max JVM最大内存
jvm.memory.committed JVM可用内存 展示并监控堆内存和Metaspace 重要
jvm.memory.used JVM已用内存 展示并监控堆内存和Metaspace 重要
jvm.buffer.memory.used JVM缓冲区已用内存
jvm.buffer.count 当前缓冲区数
jvm.threads.daemon JVM守护线程数 显示在监控页面
jvm.threads.live JVM当前活跃线程数 显示在监控页面;监控达到阈值时报警 重要
jvm.threads.peak JVM峰值线程数 显示在监控页面
jvm.classes.loaded 加载classes数
jvm.classes.unloaded 未加载的classes数
jvm.gc.memory.allocated GC时,年轻代分配的内存空间
jvm.gc.memory.promoted GC时,老年代分配的内存空间
jvm.gc.max.data.size GC时,老年代的最大内存空间
jvm.gc.live.data.size FullGC时,老年代的内存空间
jvm.gc.pause GC耗时 显示在监控页面

TOMCAT指标

参数 参数说明 是否监控 监控手段 重要度
tomcat.sessions.created tomcat已创建session数
tomcat.sessions.expired tomcat已过期session数
tomcat.sessions.active.current tomcat活跃session数
tomcat.sessions.active.max tomcat最多活跃session数 显示在监控页面,超过阈值可报警或者进行动态扩容 重要
tomcat.sessions.alive.max.second tomcat最多活跃session数持续时间
tomcat.sessions.rejected 超过session最大配置后,拒绝的session个数 显示在监控页面,方便分析问题
tomcat.global.error 错误总数 显示在监控页面,方便分析问题
tomcat.global.sent 发送的字节数
tomcat.global.request.max request最长时间
tomcat.global.request 全局request次数和时间
tomcat.global.received 全局received次数和时间
tomcat.servlet.request servlet的请求次数和时间
tomcat.servlet.error servlet发生错误总数
tomcat.servlet.request.max servlet请求最长时间
tomcat.threads.busy tomcat繁忙线程 显示在监控页面,据此检查是否有线程夯住
tomcat.threads.current tomcat当前线程数(包括守护线程) 显示在监控页面 重要
tomcat.threads.config.max tomcat配置的线程最大数 显示在监控页面 重要
tomcat.cache.access tomcat读取缓存次数
tomcat.cache.hit tomcat缓存命中次数

CPU指标

参数 参数说明 是否监控 监控手段 重要度
system.cpu.count CPU数量
system.load.average.1m load average 超过阈值报警 重要
system.cpu.usage 系统CPU使用率
process.cpu.usage 当前进程CPU使用率 超过阈值报警
http.server.requests http请求调用情况 显示10个请求量最大,耗时最长的URL;统计非200的请求量 重要
process.uptime 应用已运行时间 显示在监控页面
process.files.max 允许最大句柄数 配合当前打开句柄数使用
process.start.time 应用启动时间点 显示在监控页面
process.files.open 当前打开句柄数 监控文件句柄使用率,超过阈值后报警 重要

 

接口端点说明

ID 描述
auditevents 公开当前应用程序的审核事件信息。需要AuditEventRepository bean
beans 显示应用程序中所有spring bean的完整列表
caches 公开可用的缓存
conditions 显示在配置和自动配置类上评估的条件,以及它们匹配或不匹配的原因
configprops 显示所有@ConfigurationProperties的整理列表
env 显示Spring的可配置环境中公开属性。 ConfigurableEnvironment
flyway 显示已应用的所有Flyway数据库迁移。需要一个或多个Flyway beans
health 显示应用程序运行状况信息
httptrace 显示HTTP跟踪信息(默认情况下,最后100个HTTP请求-响应交换)。需要HttpTraceRepository bean
info 显示任意应用程序信息
integrationgraph 显示了Spring集成图。需要依赖于spring集成核心
loggers 显示并修改应用程序中记录器的配置
liquibase 显示已应用的任何Liquibase数据库迁移,至少需要一个 Liquibase bean
metrics 显示当前应用程序的“指标”信息
mappings 显示所有@RequestMapping路径的整理列表
scheduledtasks 显示应用程序中的计划任务
sessions 允许从支持Spring会话的会话存储中检索和删除用户会话。需要使用Spring Session对响应式Web应用程序的支持时不可用
shutdown 允许应用程序正常关闭。默认情况下禁用
threaddump 执行线程转储
# 开启或关闭指定接口端点: management.endpoint.<id>.enabled
management:
  endpoint:
    shutdown:
      enabled: true

开启后, 访问: http://localhost:8310/actuator/shutdown 进行关闭应用程序(POST请求)

如果您的应用程序是web应用程序(Spring MVC、Spring WebFlux或Jersey),则可以使用以下附加端点:

ID 描述
heapdump 返回hprof堆转储文件
jolokia 通过HTTP公开jmxbean(当Jolokia位于类路径上时,WebFlux不可用)。需要依赖jolokia core
logfile 返回日志文件的内容(如果logging.file.name日志或者logging.file.path属性已设置)。支持使用HTTP范围头来检索日志文件的部分内容
prometheus 以Prometheus服务器可以擦除的格式公开度量。需要micrometer-registry-prometheus`依赖

 

Reference

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章