Spring Boot —— Actuator 監控、檢測、審計、應用情況採集

Spring Boot —— Actuator 監控、檢測、審計、應用情況採集

前言

是Spring Boot 一個非常強大功能,可以對應用程序進行監視和管理,通過restful api請求來監管、審計、收集應用的運行情況,針對微服務而言它是必不可少的一個組件。

組成部分

Endpoints

actuator核心部分,用來監視應用程序及交互,spring-boot-actuator中已經內置非常多的Endpoints(health、info、beans、httptrace、shutdown等等),同時,也允許程序員自定義擴展端點.

Spring Boot 2.0 中的端點相較之前版本有較大不同,使用時需注意。另外端點的監控機制也有很大的不同,啓用了不代表可以直接訪問,還需要將其暴露出來,傳統的management.security管理已被標記爲不推薦。

內置Endpoints

id desc Sensitive
auditevents 顯示當前應用程序的審計事件信息 Yes
beans 顯示應用Spring Beans的完整列表 Yes
caches 顯示可用緩存信息 Yes
conditions 顯示自動裝配類的狀態及及應用信息 Yes
configprops 顯示所有 @ConfigurationProperties 列表 Yes
env 顯示 ConfigurableEnvironment 中的屬性 Yes
flyway 顯示 Flyway 數據庫遷移信息 Yes
health 顯示應用的健康信息(未認證只顯示status,認證顯示全部信息詳情) No
info 顯示任意的應用信息(在資源文件寫info.xxx即可) No
liquibase 展示Liquibase 數據庫遷移 Yes
metrics 展示當前應用的 metrics 信息 Yes
mappings 顯示所有 @RequestMapping 路徑集列表 Yes
scheduledtasks 顯示應用程序中的計劃任務 Yes
sessions 允許從Spring會話支持的會話存儲中檢索和刪除用戶會話 Yes
shutdown 允許應用以優雅的方式關閉(默認情況下不啓用) Yes
threaddump 執行一個線程dump Yes
httptrace 顯示HTTP跟蹤信息(默認顯示最後100個HTTP請求 - 響應交換) Yes

配置

配置pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

如果要訪問info接口想獲取maven中的屬性內容請記得添加如下內容

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>build-info</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

yml配置actuator

yml中配置actuator,其中info開頭的屬性,就是訪問info端點中顯示的相關內容,值得注意的是Spring Boot2.x中,默認只開放了info、health兩個端點,其餘需要自己通過配置management.endpoints.web.exposure.include屬性來加載(包含include 自然就有 exclue,等其它屬性)。如果想單獨操作某個端點,可使用management.endpoint.端點.enabled屬性進行啓用或禁用。

# 描述信息
info:
  blog-url: http://winterchen.com
  author: Luis
  # 能獲取到maven中配置的版本信息
  version: @project.version@

# 加載所有的端點/默認只加載了 info/health
management:
  endpoints:
    web:
      exposure:
        include: "*"“
  endpoint:
    health:
      show-details: always
    # 關閉指定的端點
    shutdown:
      enabled: false
#    # 路徑映射,將health路徑映射成rest_health,那麼在訪問health路徑將爲404,因爲原請求地址"health"已變成"rest_health",通常不建議使用此功能:
#    web:
#      path-mapping:
#        health: rest_health

{"blog-url":"http://winterchen.com","author":"Luis","version":"1.0-SNAPSHOT"}

自定義Actuator(學習重點)

以上是默認的以及自帶的配置,實際應用中有時候默認並不能滿足我們的要求,比如Spring Boot默認的的配置並不能滿足實際應用需求。

  • 默認裝配 HealthIndicators
    下列是依賴spring-boot-xxx-starter後相關HealthIndicator的實現(通過maangement.health.defaults.enabled屬性可以禁用它們),但想要獲取一些特定的,例如監控某個特定業務是否可用時,就需要自定義HealthIndicator了
屬性 描述
CassandraHealthIndicator 檢查Cassandra數據庫是否啓動
DiskSpaceHealthIndicator 檢查磁盤空間不足
DataSourceHealthIndicator 檢查是否可以獲得連接DataSource
ElasticsearchHealthIndicator 檢查Elasticsearch集羣是否啓動
InfluxDbHealthIndicator 檢查InfluxDB服務器是否啓動
JmsHealthIndicator 檢查JMS代理是否啓動
MailHealthIndicator 檢查郵件服務器是否啓動
MongoHealthIndicator 檢查Mongo數據庫是否啓動
Neo4jHealthIndicator 檢查Neo4j服務器是否啓動
RabbitHealthIndicator 檢查Rabbit服務器是否啓動
RedisHealthIndicator 檢查Redis服務器是否啓動
SolrHealthIndicator 檢查Solr服務器是否啓動

示例1:健康端點

要求:實現HealthIndicator接口,自定義檢測內容,並返回狀態UP還是DOWN,來嘗試一下吧。

package com.frank.sb.actuator.config;

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

@Component("frankHealthIndicator_1")
public class MyHealthIndicator implements HealthIndicator {

    private static final String VERSION = "V1.0.0";

    /**
     * 自定義檢測check函數內容是否爲0的例子。
     * 我們可以訪問
     * @return
     */
    @Override
    public Health health() {
        // 獲取自定義check內容
        int code = check();
        // 當check不等於0時,DOWN:代表運行錯誤
        if(code != 0) {
            Health.down().withDetail("code", code).withDetail("version", VERSION).build();
        }
        // 當check結果爲0時,UP:代表運行正常
        return  Health.up().withDetail("code", code).withDetail("version", VERSION).up().build();
    }

    private int check() {
        return 0;
    }
}

  • 訪問查看結果

http://localhost:8082/actuator/health

{
    "status": "UP",
    "details": {
        "frank": {
            "status": "UP",
            "details": {
                "code": 0,
                "version": "V1.0.0"
            }
        },
        "diskSpace": {
            "status": "UP",
            "details": {
                "total": 500068036608,
                "free": 50143068160,
                "threshold": 10485760
            }
        }
    }
}

示例2:健康端點

繼承AbstractHealthIndicator抽象類,重寫doHealthCheck方法,功能比示例1更強大,默認DataSourceHealthIndicator、RedisHealthIndicator都是這種寫法,內容回調中還做了異常處理。
代碼示例如下:

package com.frank.sb.actuator.config;

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

/**
 * 自定義健康端點
 * 功能強大一些。
 * DataSourceHealthIndicator 與 RedisHealthIndicator 寫法相同
 */
@Component("frankHealthIndicator_2")
public class MyAbstractHealthIndicator extends AbstractHealthIndicator {
    
    private static final String VERSION = "V1.0.0";
    
    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        int code = check();
        if(code != 0) {
            builder.down().withDetail("code", code).withDetail("version", VERSION).build();
        }
        builder.withDetail("code", code).withDetail("version", VERSION).up().build();
    }
    
    private int check() {
        return 0;
    }
}

  • 訪問查看結果

http://localhost:8082/actuator/health

{
    "status": "UP",
    "details": {
        "frank": {
            "status": "UP",
            "details": {
                "code": 0,
                "version": "V1.0.0"
            }
        },
        "diskSpace": {
            "status": "UP",
            "details": {
                "total": 500068036608,
                "free": 50143068160,
                "threshold": 10485760
            }
        }
    }
}

如果能訪問到,並顯示上面信息,代表配置成功。

自定義端點

info、health都是spring-boot-actuator內置的,實現自定義端點需要使用@Endpoint、@ReadOperation、@WriteOperation、@DeleteOperation 註解。

實現自定義端點註解介紹

註解 解釋
@Endpoint 構建 rest api 的唯一路徑
@ReadOperation GET請求,響應狀態爲 200 如果沒有返回值響應 404(資源未找到)
@WriteOperation POST請求,響應狀態爲 200 如果沒有返回值響應 204(無響應內容)
@DeleteOperation DELETE請求,響應狀態爲 200 如果沒有返回值響應 204(無響應內容)

自定義端點示例

編寫自定義端點
package com.frank.sb.actuator.config;

import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;

import java.util.HashMap;
import java.util.Map;

/**
 * <p>@Endpoint 是構建 rest 的唯一方式 </p>
 * 不同請求的操作,調用時缺少必需參數,或者使用無法轉換爲所需類型的參數,則不會調用操作方法,響應狀態將爲400(錯誤請求)
 * <P>@ReadOperation = GET 響應狀態爲 200 如果沒有返回值響應 404(資源未找到) </P>
 * <P>@WriteOperation = POST 響應狀態爲 200 如果沒有返回值響應 204(無響應內容) </P>
 * <P>@DeleteOperation = DELETE 響應狀態爲 200 如果沒有返回值響應 204(無響應內容) </P>
 *
 * Created by Donghua.Chen on 2018/7/12.
 */
@Endpoint(id = "nancy")
public class MyEndPoint {

    @ReadOperation
    public Map<String, String> hello() {
        Map<String, String> result = new HashMap<>();
        result.put("author", "Nancy");
        result.put("age", "10086");
        result.put("email", "[email protected]");
        return result;
    }
}
必不可少的@Bean

如果想另自定義端點生效的話,我們需要在啓動類中設置一個必不可少的Bean,代碼如下:

  • 修改啓動類
package com.frank.sb.actuator;

import com.frank.sb.actuator.config.MyEndPoint;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/** 
 * 啓動類
 */
@SpringBootApplication
public class ActuatorApplication {
    public static void main(String[] args) {
        SpringApplication.run(ActuatorApplication.class, args);
    }

    /**
     * 啓動類中,添加下面函數,將自定義端點交由spring進行管理,令其生效
     */
    @Configuration
    static class MyEndpointConfiguration {
        @Bean
        @ConditionalOnMissingBean
        @ConditionalOnEnabledEndpoint
        public MyEndPoint myEndPoint() {
            return new MyEndPoint();
        }
    }
    
}
準備就緒,測試結果

啓動項目,並訪問:http://localhost:8082/actuator/nancy
我們可以看到下列結果:

{
    "author": "Nancy",
    "age": "10086",
    "email": "[email protected]"
}

項目地址

GitHub

總結

實際投產時,我們可以根據不同的業務,自定義端點,來檢測系統關鍵功能和組件是否可用。

本博文內容均來源於網絡

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