天天看點

SpringBoot如何利用Actuator來監控應用?

Actuator是什麼?

官網:

​​Spring Boot Actuator: Production-ready Features​​

先從官網摘幾句文绉绉的解釋:

  • SpringBoot可以幫助你再将應用程式推向生産環境時對其進行監視和管理。
  • 你可以選擇使用http斷點或JMX來管理和監視應用程式。
  • 審計【auditing】、健康【health】和名額收集【metrics gathering】可以自動應用到你的應用程式中。

總結一下就是:Actuator就是用來監控你的應用程式的。

快速開始

引入依賴

<!--Actuator-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--Spring MVC 自動化配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>      

一般來說這兩個依賴都是互相配合的。

yml與自動配置

下面是一段yml的配置:

server:
  port: 8081
management:
  endpoints:
    web:
      base-path: /actuator # Actuator 提供的 API 接口的根目錄
      exposure:
        include: '*'  # 需要開放的端點
        exclude: # 需要排除的端點      
  • ​management.endpoints.web​

    ​​對應的配置類是:​

    ​org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties​

    ​。
  • 相關的自動配置在​

    ​org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration​

    ​中完成,感興趣的同學可以檢視一下源碼。
  • basePath是Actuator提供的API接口的根目錄,預設配置就是​

    ​/actuator​

    ​。
  • Exposure.include表示需要開放的端點,預設隻打開​

    ​health​

    ​​和​

    ​info​

    ​​兩個斷點,設定​

    ​*​

    ​可以開放所有端點 。
  • Exposure.include表示排除的端點,設定​

    ​*​

    ​為排除所有的端點。

主程式類

@SpringBootApplication
public class SpringBootActuatorApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootActuatorApplication.class, args);
    }

}      

測試

通路​

​http://localhost:8081/actuator/health​

​,得到應用的健康資訊如下:

{
  status: "UP"  // 開啟
}      

Endpoints

由于我們設定開放了所有的Endpoints,啟動程式時,我們能夠看到控制台輸出:

[  restartedMain] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 13 endpoint(s) beneath base path '/actuator'      

說的很清楚,總共暴露了内置的13個端點,這些端點,SpringBoot文檔已經交代地非常詳細啦。

其實内置的端點不止13個,官方文檔說:每個端點可以被​

​enabled or disabled​

​​和​

​exposed over HTTP or JMX​

​。隻有當端點同時enabled和exposed的時候才可用,内置的端點也隻有在自動配置生效的時候才可用。

大多數的應用程式會選擇HTTP暴露端點,我們可以通過​

​/actuator/health​

​​通路ID為​

​health​

​的端點。

官方列舉的所有端點清單

JMX和web共有的

ID Description
auditevents 顯示目前應用程式的審計事件資訊,需要 AuditEventRepository bean.
beans 展示你應用程式中Spring Beans的完整清單
caches 顯示可用緩存資訊
conditions 顯示自動裝配類的狀态及是否比對
configprops 顯示所有@ConfigurationProperties清單
env 顯示ConfigurableEnvironment中的屬性
flyway 顯示Flyway資料庫遷移資訊,需要一個或多個 Flyway beans
health 顯示應用的健康資訊(未認證隻顯示status,認證顯示全部資訊詳情)
httptrace 顯示HTTP跟蹤資訊(預設顯示最後100個HTTP請求 - 響應交換),需要一個 HttpTraceRepository bean.
info 顯示任意的應用資訊
integrationgraph 顯示Spring Integration圖,需要 spring-integration-core依賴
loggers 顯示和修改應用程式中日志記錄器的配置。
liquibase 展示Liquibase 資料庫遷移,需要一個或多個 Liquibase beans.
metrics 展示目前應用的 metrics 資訊
mappings 顯示所有@RequestMapping 路徑集清單
scheduledtasks 顯示應用程式中的計劃任務
sessions 允許從Spring會話支援的會話存儲中檢索和删除使用者會話。 需要一個 Servlet-based web application using Spring Session.
shutdown 允許應用以優雅的方式關閉(預設情況下不啟用)
startup 顯示由ApplicationStartup收集的啟動步驟. 将 SpringApplication 配置為BufferingApplicationStartup.
threaddump 執行一個線程dump

如果你的是web應用 (Spring MVC, Spring WebFlux, or Jersey),你可以使用下面這些額外的端點:

ID Description
heapdump 傳回一個 hprof 堆轉儲檔案
jolokia 通過HTTP公開JMXbean 當Jolokia在類路徑上時,不适用于WebFlux). 需要 jolokia-core依賴
logfile 傳回日志檔案的内容(如果 logging.file.name 或logging.file.path 屬性已經被設定) 支援使用HTTPrange标頭來檢索部分日志檔案的内容
prometheus 以Prometheus伺服器可以抓取的格式公開名額。需要依賴于micrometer-registry-prometheus。

啟動端點

如果你希望啟動某個端點,你可以按照​

​management.endpoint.<id>.enabled​

​​的配置啟動,以​

​shutdown​

​端點為例:

management:
  endpoint:
    shutdown:
      enabled: true      

如果你隻希望啟動某個端點,你可以向下面這樣:

management:
  endpoints:
    enabled-by-default: false # 不啟用預設配置
  endpoint:
    info:
      enabled: true      

這個示例,隻會啟用info端點。

暴露端點

端點可能會包含銘感資訊,考慮暴露的時候應當慎重考慮。

  • web程式預設暴露的端點有且僅有兩個:​

    ​health​

    ​​和​

    ​info​

    ​。
  • JMX程式預設暴露所有的端點。

我們可以使用​

​include​

​​和​

​exclude​

​屬性來控制端點是否需要暴露。下面是兩個例子

一、不讓JMX暴露所有端點,隻讓它暴露​

​health​

​​和​

​info​

​兩個端點。

management:
  endpoints:
    jmx:
      exposure:
        include: "health,info"      

二、暴露web除​

​env​

​​和​

​beans​

​之外的所有端點。

management:
  endpoints:
    web:
      exposure:
        include: "*"
        exclude: "env,beans"


management.endpoints.web.exposure.include=*  
management.endpoints.web.exposure.exclude=env,beans      

配置端點

端點将會自動緩存對不帶任何參數的讀取操作的響應。你可以使用​

​cache.time-to-live​

​屬性配置。

以下示例将Bean端點的緩存的生存時間設定為10秒。

management:
  endpoint:
    beans:
      cache:
        time-to-live: "10s"      

發現頁面

預設你可以通路​

​/actuator​

​頁面獲得所有的端點資訊:

{
  _links: {
    self: {
      href: "http://localhost:8081/actuator",
      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
    }
  }
}      

跨域支援

預設情況下,CORS支援是禁用的,并且僅在設定了​

​management.endpoints.web.cors.allowed-origins​

​屬性後才啟用。以下配置允許來自example.com域的GET和POST調用:

management:
  endpoints:
    web:
      cors:
        allowed-origins: "https://example.com"
        allowed-methods: "GET,POST"      

完整的選項可以檢視:CorsEndpointProperties

實作一個定義的端點

我們直接來看一個例子吧:

@Component  // 讓Spring容器管理
@Endpoint(id = "myEndPoint") //web和jmx公用, @WebEndpoint表示指定web
public class MyEndpoint {

    Runtime runtime = Runtime.getRuntime();

    @ReadOperation // 讀操作
    public Map<String, Object> getData() {
        Map<String, Object> map = new HashMap<>();
        map.put("available-processors", runtime.availableProcessors());
        map.put("free-memory", runtime.freeMemory());
        map.put("max-memory", runtime.maxMemory());
        map.put("total-memory", runtime.totalMemory());
        return map;
    }
}      
  • ​@Component​

    ​表明讓這個bean給Spring容器管理。
  • ​@Endpoint​

    ​​标注這是個端點,類似的還有​

    ​@WebEndpoint​

    ​标注的是特指web程式。
  • ​id = "myEndPoint"​

    ​​限制通路端點的路徑:​

    ​/actuator/myEndPoint​

    ​。
  • ​@ReadOperation​

    ​​規定HTTP請求的方法為GET,​

    ​@ReadOperation​

    ​​為POST,​

    ​@DeleteOperation​

    ​為DELETE。

接下來我們測試一下,再測試之前,不要忘了yml中啟動設定:

server:
  port: 8081

management:
  endpoints:
    web:
      exposure:
        include: '*' # 需要開放的端點。預設值隻打開 health 和 info 兩個端點。通過設定 * 
    enabled-by-default: false
  endpoint:
    myEndPoint:
      enabled: true      

我們暫時關閉其他所有的端點,隻關注myEndPoint端點,接着啟動程式,通路:​

​http://localhost:8081/actuator/myEndPoint​

​,獲得json資訊。

{
    max-memory: 3787980800,
    free-memory: 235775968,
    available-processors: 4,
    total-memory: 298844160
}      

實際上如果是用于SpringMVC或Spring WebFlux,我們可以使用​

​@RestControllerEndpoint​

​​或​

​@ControllerEndpoint​

​注解,定義一個更符合我們平時web開發模式的端點,你可以看一下下面這個例子。

@Component
@RestControllerEndpoint(id = "web")
public class MyWebEndPoint {
    @GetMapping("/")
    public Map<String, Object> getData() {
  // ...
        return map;
    }
}      

Health端點

端點這麼多,我們挑幾個學習一下,​

​health​

​作為預設開放的端點之一,還是需要好好了解一下的。

設定何時顯示資訊

你可以使用得到的健康資訊去檢查你的應用程式,暴露的health資訊依賴于下面兩個屬性配置:

management.endpoint.health.show-details
management.endpoint.health.show-components      

這兩個屬性可以設定的值如下:

Name Description
never 永遠不顯示
when-authorized 需要授權,通過 management.endpoint.health.roles配置
always 對所有使用者顯示

health端點通過健康訓示器​

​HealthIndicator​

​擷取不同的資源的健康資訊,且Autuator内置了多個HealthIndicator的實作,太多啦太多啦,如果需要可以看看官網 Auto-configured HealthIndicators。

另外,如果你想啟用或者禁用指定的訓示器,你可以配置​

​management.health.key.enabled​

​,key需要被替換,官網表格上有。

如果你想設定全部的,你可以配置​

​management.health.defaults.enabled​

設定順序

你可以通過以下設定顯示順序:

management:
  endpoint:
    health:
      status:
        order: "fatal,down,out-of-service,unknown,up"      

設定響應碼

響應碼反應了總體健康狀态。預設情況下,​

​OUT_OF_SERVICE​

​​和​

​DOWN​

​的映射為503,其他狀态為200。你可以按照下面的方式設定映射:

management:
  endpoint:
    health:
      status:
        http-mapping:
          down: 503
          fatal: 503
          out-of-service: 503      

自定義健康資訊

縱使,Actuator已經提供了許多内置實作,總會滿足不了我們的需求,那如何去自定義呢?

  • 注冊實作HealthIndicator接口的Spring Bean。
  • 提供health()方法的實作并傳回健康響應,包括狀态和其他需要顯示的詳細資訊。

以下代碼展示了一個案例:

import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
import java.util.Random;

@Component
public class MyHealthIndicator implements HealthIndicator {

    @Override
    public Health health() {
        // perform some specific health check
        boolean check = check();
        if (!check) {
            return Health.down().withDetail("Error Code", 0).build();
        }
        return Health.up().build();
    }

    private boolean check() {
        return new Random().nextBoolean();
    }

}      
id就是bena的名稱去掉HealthIndicator字尾,這裡id就是my。

看看相關的yml怎麼配置?

management:
  endpoints:
    web:
      exposure:
        include: '*' # 需要開放的端點。預設值隻打開 health 和 info 兩個端點。通過設定 * ,可以開放所有端點。
    enabled-by-default: false
  endpoint:
    health:
      enabled: true
      show-details: always # 何時顯示完整的健康資訊
      show-components: always
      status:
        http-mapping: # 設定不同健康狀态對應的響應狀态碼
          DOWN: 503
        order: FATAL, DOWN, OUT_OF_SERVICE, UP, UNKNOWN # 狀态排序      

測試一下,通路:​

​/actuator/health​

​,可以嘗試多點幾次,會出現UP和DOWN的情況,得到以下資訊:

{
  status: "DOWN",
  components: {
    diskSpace: {
      status: "UP",
      details: {
        total: 267117391872,
        free: 130840469504,
        threshold: 10485760,
        exists: true
      }
    },
    my: {
      status: "DOWN",
      details: {
        Error Code: 0
      }
    },
    ping: {
      status: "UP"
    }
  }
}      
  • my對應的就是我們自定義的MyHealthIndicator,裡面詳細的資訊有:狀态status,資訊details。
  • diskSpace對應DiskSpaceHealthIndicator,ping對應的是PingHealthIndicator。

其他的端點,感興趣的小夥伴可以去到官網一一測試,總之,通過這些Actuator提供的端點,我們很容易就能夠監控管理我們的應用程式。

源碼下載下傳

本文内容均為對優秀部落格及官方文檔總結而得,原文位址均已在文中參考閱讀處标注。最後,文中的代碼樣例已經全部上傳至Gitee:​​https://gitee.com/tqbx/springboot-samples-learn​​。

原作者:天喬巴夏丶