一起來學SpringBoot | 第十四篇:強大的 actuator 服務監控與管理
SpringBoot
是為了簡化Spring
應用的建立、執行、除錯、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關注業務本身而不是外部的XML配置,我們只需遵循規範,引入相關的依賴就可以輕易的搭建出一個 WEB 工程
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
中新增 spring-boot-starter-actuator
的依賴
<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>
屬性配置
在 application.properties
檔案中配置actuator
的相關配置,其中info
開頭的屬性,就是訪問info
端點中顯示的相關內容,值得注意的是Spring Boot2.x
中,預設只開放了info、health
兩個端點,剩餘的需要自己通過配置management.endpoints.web.exposure.include
屬性來載入(有include
自然就有exclude
,不做詳細概述了)。如果想單獨操作某個端點可以使用management.endpoint.端點.enabled
屬性進行啟用或禁用
# 描述資訊
info.blog-url=http://blog.battcn.com
info.author=Levin
info.version[email protected].version@
# 載入所有的端點/預設只加載了 info / health
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
# 可以關閉制定的端點
management.endpoint.shutdown.enabled=false
# 路徑對映,將 health 路徑對映成 rest_health 那麼在訪問 health 路徑將為404,因為原路徑已經變成 rest_health 了,一般情況下不建議使用
# management.endpoints.web.path-mapping.health=rest_health
簡單測試
{
"blog-url": "http://blog.battcn.com",
"author": "Levin",
"version": "0.0.1-SNAPSHOT"
}
自定義 - 重點
上面講了很多都是配置相關,以及自帶的一些端點,在實際應用中有時候預設並不能滿足我們的要求,比如Spring Boot
預設的健康端點就很有可能不能滿足
預設裝配 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.battcn.health;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
/**
* <p>自定義健康端點</p>
*
* @author Levin
* @since 2018/5/24 0024
*/
@Component("my1")
public class MyHealthIndicator implements HealthIndicator {
private static final String VERSION = "v1.0.0";
@Override
public Health health() {
int code = check();
if (code != 0) {
Health.down().withDetail("code", code).withDetail("version", VERSION).build();
}
return Health.up().withDetail("code", code)
.withDetail("version", VERSION).up().build();
}
private int check() {
return 0;
}
}
簡單測試
{
"status": "UP",
"details": {
"my1": {
"status": "UP",
"details": {
"code": 0,
"version": "v1.0.0"
}
},
"diskSpace": {
"status": "UP",
"details": {
"total": 100944310272,
"free": 55071866880,
"threshold": 10485760
}
}
}
}
健康端點(第二種方式)
繼承AbstractHealthIndicator
抽象類,重寫doHealthCheck
方法,功能比第一種要強大一點點,預設的DataSourceHealthIndicator 、 RedisHealthIndicator
都是這種寫法,內容回撥中還做了異常的處理。
package com.battcn.health;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.stereotype.Component;
/**
* <p>自定義健康端點</p>
* <p>功能更加強大一點,DataSourceHealthIndicator / RedisHealthIndicator 都是這種寫法</p>
*
* @author Levin
* @since 2018/5/24 0024
*/
@Component("my2")
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;
}
}
簡單測試
{
"status": "UP",
"details": {
"my2": {
"status": "UP",
"details": {
"code": 0,
"version": "v1.0.0"
}
},
"my1": {...},
"diskSpace": {...}
}
}
定義自己的端點
上面介紹的 info
、health
都是spring-boot-actuator
內建的,真正要實現自己的端點還得通過@Endpoint、 @ReadOperation、@WriteOperation、@DeleteOperation
。
註解介紹
不同請求的操作,呼叫時缺少必需引數,或者使用無法轉換為所需型別的引數,則不會呼叫操作方法,響應狀態將為400(錯誤請求)
@Endpoint
構建 rest api 的唯一路徑@ReadOperation
GET請求,響應狀態為 200 如果沒有返回值響應 404(資源未找到)@WriteOperation
POST請求,響應狀態為 200 如果沒有返回值響應 204(無響應內容)@DeleteOperation
DELETE請求,響應狀態為 200 如果沒有返回值響應 204(無響應內容)
package com.battcn.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;
/**
* <p>@Endpoint 是構建 rest 的唯一路徑 </p>
* 不同請求的操作,呼叫時缺少必需引數,或者使用無法轉換為所需型別的引數,則不會呼叫操作方法,響應狀態將為400(錯誤請求)
* <P>@ReadOperation = GET 響應狀態為 200 如果沒有返回值響應 404(資源未找到) </P>
* <P>@WriteOperation = POST 響應狀態為 200 如果沒有返回值響應 204(無響應內容) </P>
* <P>@DeleteOperation = DELETE 響應狀態為 200 如果沒有返回值響應 204(無響應內容) </P>
*
* @author Levin
* @since 2018/5/24 0024
*/
@Endpoint(id = "battcn")
public class MyEndPoint {
@ReadOperation
public Map<String, String> hello() {
Map<String, String> result = new HashMap<>();
result.put("author", "Levin");
result.put("age", "24");
result.put("email", "[email protected]");
return result;
}
}
以為這就大功告成了嗎,現實告訴我的是spring-boot
預設是不認識這玩意的,得申明成一個Bean
(請看 主函式
)
主函式
package com.battcn;
import com.battcn.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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Levin
*/
@SpringBootApplication
public class Chapter13Application {
public static void main(String[] args) {
SpringApplication.run(Chapter13Application.class, args);
}
@Configuration
static class MyEndpointConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint
public MyEndPoint myEndPoint() {
return new MyEndPoint();
}
}
}
測試
{
"author": "Levin",
"age": "24",
"email": "[email protected]"
}
總結
目前很多大佬都寫過關於 SpringBoot
的教程了,如有雷同,請多多包涵,本教程基於最新的 spring-boot-starter-parent:2.0.2.RELEASE
編寫,包括新版本的特性都會一起介紹…
說點什麼
- 個人QQ:1837307557
- battcn開源群(適合新手):391619659
- 微信公眾號(歡迎調戲):
battcn