Spring Boot (27) actuator服務監控與管理


actuaotr是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中添加spring-boot-starter-actuator的依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</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>

 

屬性配置

在application.yml文件中配置actuator的相關配置,其中info開頭的屬性,就是訪問info端點中顯示的相關內容,值得注意的十spring boot2.x中,默認只開放了info、health兩個端點,其余的需要自己通過配置management.endpoints.web.exposure.include屬性來加載(有include自然就有exclude)。如果想單獨操作某個端點可以使用management.endpoint.端點.enabled屬性進行啟用或者禁用。

info:
  head: head
  body: body
management:
  endpoints:
    web:
      exposure:
        #加載所有的端點,默認只加載了info、health
        include: '*'
  endpoint:
    health:
      show-details: always
    #可以關閉指定的端點
    shutdown:
      enabled: false

 

測試

啟動項目,瀏覽器輸入:http://localhost:8088/actuator/info

{"head":"head","body":"body"}

 

自定義

  上面很多都是配置相關的,以及自帶的一些端點,在實際應用中又時候默認並不能滿足我們的需求。

默認裝配HealthIndicators

  下列是依賴spring-boot-xxx-starter后相關HealthIndicator的實現(通過management.health.defaults.enabled屬性可以禁用他們),但想要獲取一些額外的信息時,自定義的作用就體現出來了。

CassandraHealthIndicator 檢查 Cassandra 數據庫是否啟動。
DiskSpaceHealthIndicator 檢查磁盤空間不足。
DataSourceHealthIndicator 檢查是否可以獲得連接 DataSource
ElasticsearchHealthIndicator 檢查 Elasticsearch 集群是否啟動。
InfluxDbHealthIndicator 檢查 InfluxDB 服務器是否啟動。
JmsHealthIndicator 檢查 JMS 代理是否啟動。
MailHealthIndicator 檢查郵件服務器是否啟動。
MongoHealthIndicator 檢查 Mongo 數據庫是否啟動。
Neo4jHealthIndicator 檢查 Neo4j 服務器是否啟動。
RabbitHealthIndicator 檢查 Rabbit 服務器是否啟動。
RedisHealthIndicator 檢查 Redis 服務器是否啟動。
SolrHealthIndicator 檢查 Solr 服務器是否已啟動。

 

健康端點(第一種方式)

  實現HealthIndicator接口,根據自己的需要判斷返回的狀態是UP還是DOWN,功能簡單。

package com.spring.boot.health;

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

@Component("my1")
public class MyHealthIndicator implements HealthIndicator {
    private  static final String VERSION = "v1.0.0";
    @Override
    public Health health() {
        int code = 0;
        if(code != 0){
            Health.down().withDetail("code",code).withDetail("version",VERSION).build();
        }
        return Health.up().withDetail("code",code).withDetail("version",VERSION).up().build();
    }
}

輸入測試地址:http://localhost:8088/actuator/health

{
    "status": "DOWN",
    "details": {
        "my1": {
            "status": "UP",
            "details": {
                "code": 0,
                "version": "v1.0.0"
            }
        },
        "rabbit": {
            "status": "DOWN",
            "details": {
                "error": "org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused (Connection refused)"
            }
        },
        "diskSpace": {
            "status": "UP",
            "details": {
                "total": 250790436864,
                "free": 67546259456,
                "threshold": 10485760
            }
        },
        "db": {
            "status": "UP",
            "details": {
                "database": "MySQL",
                "hello": 1
            }
        },
        "redis": {
            "status": "DOWN",
            "details": {
                "error": "org.springframework.data.redis.connection.PoolException: Could not get a resource from the pool; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 10.211.55.5:6379"
            }
        }
    }
}

可以看到當前項目的健康程度,由於沒有開啟linux虛擬機中的redis及rabbitMQ 所以發生異常了,平時啟動項目時不去執行是不會報錯的

 

健康端點(第二種方式)

  繼承AbstractHealthIndicator抽象類,重寫doHealthCheck方法,功能比第一種要強大一點點,默認的DataSourceHealthIndicator、RedisHealthIndicator都是這種寫法,內容回調中還做了異常的處理。

package com.spring.boot.health;

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

/**
 * 功能更強大,AbstractHealthIndicator實現了HealthIndicator接口
 */
@Component("my2")
public class MyAbstractHealthIndicator extends AbstractHealthIndicator {
    private static final String VERSION = "v1.0.1";
    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        int code = 0;
        if(code != 0){
            builder.down().withDetail("code",code).withDetail("version",VERSION).build();
        }
        builder.withDetail("code",code).withDetail("version",VERSION).up().build();
    }
}

測試 localhost:8088/actuator/health

{
    "status": "DOWN",
    "details": {
        "my2": {
            "status": "UP",
            "details": {
                "code": 0,
                "version": "v1.0.1"
            }
        },
        "my1": {
            "status": "UP",
            "details": {
                "code": 0,
                "version": "v1.0.0"
            }
        },
        "rabbit": {
            "status": "DOWN",
            "details": {
                "error": "org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused (Connection refused)"
            }
        },
        "diskSpace": {
            "status": "UP",
            "details": {
                "total": 250790436864,
                "free": 67543334912,
                "threshold": 10485760
            }
        },
        "db": {
            "status": "UP",
            "details": {
                "database": "MySQL",
                "hello": 1
            }
        },
        "redis": {
            "status": "DOWN",
            "details": {
                "error": "org.springframework.data.redis.connection.PoolException: Could not get a resource from the pool; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 10.211.55.5:6379"
            }
        }
    }
}

 

定義自己的端點

  info、health都是spring-boot-actuator內置的,真正要實現自己的端點還得通過@Endpoint、@ReadOperator、@WriteOperation、@DeleteOperation。

不同請求的操作,調用時缺少必須參數,或者使用無法轉換為所需類型的參數,則不會調用操作方法,響應狀態為400(錯誤請求)

  @Endpoint 構建rest api的唯一路徑

  @ReadOperation GET請求,響應狀態為200 如果沒有返回值響應404(資源未找到)

  @WriteOperation POST請求,響應狀態為200如果沒有返回值響應204(無響應內容)

  @DeleteOperation DELETE請求,響應狀態為200如果沒有返回值響應204(無響應內容)

package com.spring.boot.endpoint;

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

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

@Endpoint(id = "david")
public class MyEndPoint {

    @ReadOperation
    public Map<String,String> test(){
        Map<String,String> result = new HashMap<>();
        result.put("name","david");
        result.put("age","18");
        return result;
    }

}

然后在啟動類中注入bean

package com.spring.boot;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.spring.boot.endpoint.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.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;

@EnableCaching
@SpringBootApplication
public class BootApplication{

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

    @Configuration
    static class MyEndpointConfiguration{
        @Bean
        @ConditionalOnMissingBean
        @ConditionalOnEnabledEndpoint
        public MyEndPoint myEndPoint(){
            return new MyEndPoint();
        }
    }
}

測試

啟動項目 輸入測試地址:http://localhost:8088/actuator/david

{"name":"david","age":"18"}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM