服務端性能監控—— Spring Boot Actuator

服務端性能監控—— Spring Boot Actuator介紹

監控後臺服務是否正常運行,有很多指標需要我們關注,一是機器本身的狀態,比如CPU利用率、磁盤使用率、內存、網絡等,通過這些來判斷機器是否運行正常。這些是屬於機器指標,一般雲服務商會提供。今天我們要分析的是程序的性能指標,因爲即使機器正常,但程序可能已經掛了。

對java程序來說,我們主要關注JVM的狀態是否正常,希望能把一般通過jconsole得到的數據能通過監控自動獲取出趨勢圖。此時我們就需要一個非常強大的模塊:Spring Boot Actuator 來幫助獲取到應用的統計信息。Spring Boot Actuator不止能提供jvm相關信息,也能對應用相關依賴做健康檢查,功能十分強大,接入非常簡單。

給一個Maven項目增加Actuator

使用如下依賴

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

介紹Endpoints

Endpoints是Actuator中的端點,每個端點都提供了不同的功能,Actuator內置了很多Endpoints,配置就可以使用。

/health提供了應用健康信息。

/info提供了應用基本信息。

/logfile可以直接查看日誌文件等等。

同時我們也可以定義自己的Endpoints,以此來自定義想要的監控項。

查看所有endpoints

啓動項目,訪問http://localhost:8080/actuator查看,你應該能看到如下列表

{
    "_links":{
        "self":{
            "href":"http://localhost:7777/actuator",
            "templated":false
        },
        "auditevents":{
            "href":"http://localhost:7777/actuator/auditevents",
            "templated":false
        },
        "health":{
            "href":"http://localhost:7777/actuator/health",
            "templated":false
        },
        "env":{
            "href":"http://localhost:7777/actuator/env",
            "templated":false
        }
    }
}

訪問/actuator獲取到的是當前已開啓的endpoints列表,有一些文檔說很多endpoints是默認開啓的,但從Spring Boot2.0之後,因爲安全原因,大部分的endpoints都是默認關閉的了,需要在配置文件中手動開啓。

配置endpoints的開關

在配置文件中,可以通過includeexclude配置endpoint在http或jmx中是否開啓或關閉,如下。

management:
  endpoints:
    web:
      exposure:
        exclude: shutdown
        include: ["auditevents", "info", "health", "metrics", "loggers", "logfile", "httptrace", "env", "flyway", "mappings",
        "scheduledtasks", "prometheus"]
    jmx:
      exposure:
        include: * #所有

這樣就能在/actuator頁面看到大多數的endpoints了。

重要的endpoint

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

/actuator/httptrace

可以查看近期的請求詳細數據,比如參數、cookie等

####/actuator/scheduledtasks

顯示定時任務列表

{
    "cron": [
        {
            "runnable": {
                "target": "com.test.test.test.test.test.refresh"
            },
            "expression": " 0 0 0 1 1/1 ? "
        }
    ],
    "fixedDelay": [],
    "fixedRate": [],
    "custom": []
}

/actuator/mappings

顯示所有的@RequestMapping 路徑

/actuator/metrics

顯示metrics數據。

/actuator/health

health是比較重要的一個endpoint,因爲它本身自帶了許多健康檢查,可以對我們的線上監控起到非常重要的作用。

/health默認只返回一個簡單的UPDOWN的status信息,想要看到全部數據,需要修改xml配置。

management:
  endpoint:
    health:
      show-details: always #展示所有細節內容

這樣我們訪問就可以看到如下信息

// 省略了一些detail信息
{
    "status":"UP",
    "details":{
        "db":{
            "status":"UP",
            "details":{
                "dataSource":{
                    "status":"UP"
                }
            }
        },
        "refreshScope":{
            "status":"UP"
        },
        "discoveryComposite":{
            "status":"UP",
            "details":{
                "discoveryClient":{
                    "status":"UP",
                    "details":{

                    }
                },
                "eureka":{
                    "description":"Remote status from Eureka server",
                    "status":"UNKNOWN",
                    "details":{

                    }
                }
            }
        },
        "redis":{
            "status":"UP",
            "details":{
                "version":"2.8.13"
            }
        }
    }
}

可以看到db 、redis、eureka等許多重要依賴的健康信息。如果其中有一個爲DOWN,那麼應用的整體狀態就是DOWN。

我們之所以能看到這些信息的原理是它們都實現了HealthIndicator接口,會返回自身的健康狀態,如果我們需要定義自定義的健康指標的話,也是需要實現這個接口或繼承AbstractHealthIndicator,重寫其中的doHealthCheck方法,後面會會講解這種方式。

已經實現這個接口的有

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

自定義健康指標

比如我的項目中,並沒有用es默認的client,而是自己去創建一個es的RestLowLevelClientt,以此來跳過https證書檢查。這樣我就沒有辦法使用ElasticsearchHealthIndicator,因爲它肯定會一直返回down,只能自己實現一個HealthIndicator接口或繼承AbstractHealthIndicator類。如下代碼(檢查邏輯是參照的ElasticsearchHealthIndicator

public class EsRestLowLevelClientHealthIndicator  extends AbstractHealthIndicator {
    private static final String RED_STATUS = "red";
    private final JsonParser jsonParser;

    private RestLowLevelClient restLowLevelClient;

    @Autowired
    public EsRestLowLevelClientHealthIndicator(RestLowLevelClient restLowLevelClient) {
        this.restLowLevelClient = restLowLevelClient;
        this.jsonParser = JsonParserFactory.getJsonParser();;
    }

    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        Response response = this.restLowLevelClient.performRequest(new Request("GET", "/_cluster/health/"));
        StatusLine statusLine = response.getStatusLine();
        if (statusLine.getStatusCode() != 200) {
            builder.down();
            builder.withDetail("statusCode", statusLine.getStatusCode());
            builder.withDetail("reasonPhrase", statusLine.getReasonPhrase());
        } else {
            InputStream inputStream = response.getEntity().getContent();
            Throwable var5 = null;

            try {
                this.doHealthCheck(builder, StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8));
            } catch (Throwable var14) {
                var5 = var14;
                throw var14;
            } finally {
                if (inputStream != null) {
                    if (var5 != null) {
                        try {
                            inputStream.close();
                        } catch (Throwable var13) {
                            var5.addSuppressed(var13);
                        }
                    } else {
                        inputStream.close();
                    }
                }

            }

        }
    }

    private void doHealthCheck(Health.Builder builder, String json) {
        Map<String, Object> response = this.jsonParser.parseMap(json);
        String status = (String)response.get("status");
        if (RED_STATUS.equals(status)) {
            builder.outOfService();
        } else {
            builder.up();
        }

        builder.withDetails(response);
    }
}

這個類加載到Spring中,在訪問/actuator/health時就會得到如下信息。

{
    "status":"UP",
    "details":{
        "esRestLowLevelClient":{
            "status":"UP",
            "details":{
                "cluster_name":"shark",
                "status":"yellow",
                "timed_out":false,
                "number_of_nodes":26,
                "number_of_data_nodes":26,
                "active_primary_shards":10009,
                "active_shards":20105,
                "relocating_shards":0,
                "initializing_shards":0,
                "unassigned_shards":14,
                "delayed_unassigned_shards":0,
                "number_of_pending_tasks":0,
                "number_of_in_flight_fetch":0,
                "task_max_waiting_in_queue_millis":0,
                "active_shards_percent_as_number":99.93041403648293
            }
        }
    }
}

可以看到我們自定義的esRestLowLevelClient指標爲UP狀態。

通過/actuator/health,我們可以寫一個定時器對應用做黑盒監控,判斷返回值是否爲UP,否則報警,就可以很容易地對應用和依賴做出監控了。

結語

上面主要介紹了Spring Boot Actuator的作用和用法,可以看出它是一個開箱即用、功能強大的組件,除了上面介紹了的還有修改日誌等級、管理session等功能,大家可以嘗試加入到自己項目中,能大大地提高監控效率。下一篇我們會分享如何把jvm監控數據展示到Grafana中,得到詳細的性能監控圖表。如下圖

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-QmTXB05r-1585240421107)(/Users/gaoshuo/Library/Application Support/typora-user-images/image-20200327003146815.png)]

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