SpringBoot第二十二篇:應用監控之Actuator


作者:追夢1819
原文:https://www.cnblogs.com/yanfei1819/p/11226397.html
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

引言

  很多文章都將 SpringBoot Actuator 的 Endpoint 翻譯為 "端點"。不過我認為這這翻譯失去了原有的意思。故本文中的 endpoint 依舊是 endpoint,不翻譯為"端點"。

  通過引入 spring-boot-starter-actuator ,可以使用 SpringBoot 為我們提供的准生產環境下的應用監控和管理功能。我們可以通過 HTTP、JMX、SSH協議進行操作。自動得到審計、監控和指標操作。


步驟:

  1. 引入maven依賴;
  2. 通過 HTTP 方式訪問監控端點;
  3. 可進行 shutdown(post提交,此端點默認關閉)。

原生endpoint

  SpringBoot 的 Actuator 有很多原生的端點,詳細查看官網。Spring Boot 2.0 中的端點和之前的版本有較大不同,使用時需注意。啟動時不是可以直接訪問,需要先將其暴露出來。

本文中,我們講述幾個常用的端點。

  1. health

    主要用來檢查應用的運行狀態。如果應用有異常,同時給我們反饋異常原因。比如數據庫連接異常,磁盤空間過小等異常。

  2. info

    自定義應用程序的配置信息。

    例如,在配置文件中配置如下信息:

    info.app.name=actuator
    info.app.versoin=1.0.0
    info.app.data=2019-06-25 12:00:00
    info.app.author=yanfei1819
    

    啟動項目,訪問http://localhost:8080/actuator/info,可以得到如下響應:

    {"app":{"name":"actuator","versoin":"1.0.0","data":"2019-06-25 12:00:00","author":"yanfei1819"}}
    
  3. beans

    該 endpoint 展示了 bean 的別名、類型、是否單例、類的地址、依賴等信息。

  4. conditions

    Spring Boot 的自動配置功能非常便利,但有時候也意味着出問題比較難找出具體的原因。使用 conditions 可以在應用運行時查看代碼了某個配置在什么條件下生效,或者某個自動配置為什么沒有生效。

  5. heapdump

    展示Jvm 的堆文件 heapdump。

  6. shutdown

    遠程關閉應用的端點,不過需要注意兩點:

    • 需要在配置文件中配置 management.endpoint.shutdown.enabled=true
    • 只支持 POST 請求。
  7. mappings

    程序中所有的 URI 路徑,以及與控制器的關系。

  8. threaddump

    查看線程信息,例如線程名、線程ID、線程的狀態、是否等待鎖資源等。


使用

創建項目,引入 maven 依賴:

<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>

啟動項目,控制台打印信息:

可以看出此時只暴露了兩個 endpoint。

訪問 http://localhost:8080/actuator ,可以看到兩個端點是:

{
	"_links": {
		"self": {
			"href": "http://localhost:8080/actuator",
			"templated": false
		},
		"health": {
			"href": "http://localhost:8080/actuator/health",
			"templated": false
		},
		"health-component": {
			"href": "http://localhost:8080/actuator/health/{component}",
			"templated": true
		},
		"health-component-instance": {
			"href": "http://localhost:8080/actuator/health/{component}/{instance}",
			"templated": true
		},
		"info": {
			"href": "http://localhost:8080/actuator/info",
			"templated": false
		}
	}
}

如果我們需要訪問所有的原生 endpoint,需要在配置文件中加入:management.endpoints.web.exposure.include=*

重新啟動項目,控制台日志是:

訪問 http://localhost:8080/actuator ,可以看到所有端點是:

{
	"_links": {
		"self": {
			"href": "http://localhost:8080/actuator",
			"templated": false
		},
		"auditevents": {
			"href": "http://localhost:8080/actuator/auditevents",
			"templated": false
		},
		"beans": {
			"href": "http://localhost:8080/actuator/beans",
			"templated": false
		},
		"caches-cache": {
			"href": "http://localhost:8080/actuator/caches/{cache}",
			"templated": true
		},
		"caches": {
			"href": "http://localhost:8080/actuator/caches",
			"templated": false
		},
		"health": {
			"href": "http://localhost:8080/actuator/health",
			"templated": false
		},
		"health-component": {
			"href": "http://localhost:8080/actuator/health/{component}",
			"templated": true
		},
		"health-component-instance": {
			"href": "http://localhost:8080/actuator/health/{component}/{instance}",
			"templated": true
		},
		"conditions": {
			"href": "http://localhost:8080/actuator/conditions",
			"templated": false
		},
		"configprops": {
			"href": "http://localhost:8080/actuator/configprops",
			"templated": false
		},
		"env": {
			"href": "http://localhost:8080/actuator/env",
			"templated": false
		},
		"env-toMatch": {
			"href": "http://localhost:8080/actuator/env/{toMatch}",
			"templated": true
		},
		"info": {
			"href": "http://localhost:8080/actuator/info",
			"templated": false
		},
		"loggers": {
			"href": "http://localhost:8080/actuator/loggers",
			"templated": false
		},
		"loggers-name": {
			"href": "http://localhost:8080/actuator/loggers/{name}",
			"templated": true
		},
		"heapdump": {
			"href": "http://localhost:8080/actuator/heapdump",
			"templated": false
		},
		"threaddump": {
			"href": "http://localhost:8080/actuator/threaddump",
			"templated": false
		},
		"metrics": {
			"href": "http://localhost:8080/actuator/metrics",
			"templated": false
		},
		"metrics-requiredMetricName": {
			"href": "http://localhost:8080/actuator/metrics/{requiredMetricName}",
			"templated": true
		},
		"scheduledtasks": {
			"href": "http://localhost:8080/actuator/scheduledtasks",
			"templated": false
		},
		"httptrace": {
			"href": "http://localhost:8080/actuator/httptrace",
			"templated": false
		},
		"mappings": {
			"href": "http://localhost:8080/actuator/mappings",
			"templated": false
		}
	}
}

  讀者可以逐個訪問,查看對應的返回信息。

  當然,也可以通過配置 management.endpoints.web.exposure.exclude=info,trace 選擇部分 endpoint 暴露。

  同時,Actuator 默認所有的監控點路徑都在/actuator/*,當然如果有需要這個路徑也支持定制。management.endpoints.web.base-path=/manage


自定義endpoint

以下:

package com.yanfei1819.actuator.endpoint;

import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by 追夢1819 on 2019-06-25.
 */
@Configuration
@Endpoint(id = "customize-endpoint") // 構建 rest api 的唯一路徑
public class CustomizeEndPoint {
    @ReadOperation
    public Map<String, Object> endpoint() {
        Map<String, Object> map = new HashMap<>(16);
        map.put("message", "this is customize endpoint");
        return map;
    }
}

在配置文件中使其暴露:

management.endpoints.web.exposure.include=customize-endpoint

啟動程序,訪問 management.endpoints.web.exposure.include=customize-endpoint ,可以得到endpoint:

{
	"_links": {
		"self": {
			"href": "http://localhost:8080/actuator",
			"templated": false
		},
		"customize-endpoint": {
			"href": "http://localhost:8080/actuator/customize-endpoint",
			"templated": false
		}
	}
}

再訪問返回的endpoint地址,得到相應:

{"message":"this is customize endpoint"}

可驗證自定義 endpoint 成功。


總結

  對於作者來說,這個功能核心是對 endpoints 的理解(我對該功能的使用總結,大部分時間也是耗在了這個上面)。理解了每一個 endpoint ,基本大的方向就掌握了。剩下的就是細節問題了(細節問題無非就是"慢工出細活",簡單)。

  另一個問題, Actuctor 的功能是實現了,可是大家有沒有覺得用起來很別扭?查看一個監控信息,就訪問一個路徑,得到的就一連串的JSON,繁瑣、復雜、不夠直觀。這實屬讓運維同學抓狂的問題。有沒有好的解決方案呢?且聽下回分解。


參考

SpringBoot官網


![](https://img2018.cnblogs.com/blog/1183871/201907/1183871-20190722155821232-374443563.png)


免責聲明!

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



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