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

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