天天看點

spring boot 1.5.4 之監控Actuator(十四)

1      actuator簡介

在Spring Boot的衆多StarterPOMs中有一個特殊的子產品,它不同于其他子產品那樣大多用于開發業務功能或是連接配接一些其他外部資源。它完全是一個用于暴露自身資訊的子產品,是以很明顯,它的主要作用是用于監控與管理,它就是:spring-boot-starter-actuator。

spring-boot-starter-actuator子產品的實作對于實施微服務的中小團隊來說,可以有效地減少監控系統在采集應用名額時的開發量。當然,它也并不是萬能的,有時候我們也需要對其做一些簡單的擴充來幫助我們實作自身系統個性化的監控需求。下面,我們将詳細的介紹一些關于spring-boot-starter-actuator子產品的内容,包括它的原生提供的端點以及一些常用的擴充和配置方式。

在mybatis-spring-boot項目的pom檔案中引入actuator依賴:

<dependency>

        <!--引入spring bootactuator監控 -->

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-actuator</artifactId>

      </dependency>

啟動項目,檢視控制台效果:

<a href="https://s1.51cto.com/wyfs02/M02/A6/77/wKioL1nPUKmTgcFUAAFNwwC3CLY698.png" target="_blank"></a>

上圖顯示了一批端點定義,這些端點并非我們自己在程式中建立,而是由spring-boot-starter-actuator子產品根據應用依賴和配置自動建立出來的監控和管理端點。通過這些端點,我們可以實時的擷取應用的各項監控名額,比如:通路/health端點,我們可以獲得如下傳回的應用健康資訊:

<a href="https://s2.51cto.com/wyfs02/M02/A6/77/wKioL1nPULKAdLGIAAA90C9qglY435.png" target="_blank"></a>

列舉一些主要的endpoints:

<a href="https://s5.51cto.com/wyfs02/M00/07/C5/wKiom1nPUQKRRM0cAACQVsG7AC0839.png" target="_blank"></a>

通過在快速入門示例中添加spring-boot-starter-actuator子產品,我們已經對它有了一個初步的認識。接下來,我們詳細介紹一下spring-boot-starter-actuator子產品中已經實作的一些原生端點。如果根據端點的作用來說,我們可以原生端點分為三大類:

應用配置類:擷取應用程式中加載的應用配置、環境變量、自動化配置報告等與Spring Boot應用密切相關的配置類資訊。

度量名額類:擷取應用程式運作過程中用于監控的度量名額,比如:記憶體資訊、線程池資訊、HTTP請求統計等。

操作控制類:提供了對應用的關閉等操作類功能。

下面我們來詳細了解一下這三類端點都分别可以為我們提供怎麼樣的有用資訊和強大功能,以及我們如何去擴充和配置它們。

由于Spring Boot為了改善傳統Spring應用繁雜的配置内容,采用了包掃描和自動化配置的機制來加載原本集中于xml檔案中的各項内容。雖然這樣的做法,讓我們的代碼變得非常簡潔,但是整個應用的執行個體建立和依賴關系等資訊都被離散到了各個配置類的注解上,這使得我們分析整個應用中資源和執行個體的各種關系變得非常的困難。而這類端點就可以幫助我們輕松的擷取一系列關于Spring 應用配置内容的詳細報告,比如:自動化配置的報告、Bean建立的報告、環境屬性的報告等。

/autoconfig:該端點用來擷取應用的自動化配置報告,其中包括所有自動化配置的候選項。同時還列出了每個候選項自動化配置的各個先決條件是否滿足。是以,該端點可以幫助我們友善的找到一些自動化配置為什麼沒有生效的具體原因。該報告内容将自動化配置内容分為兩部分:

positiveMatches中傳回的是條件比對成功的自動化配置

negativeMatches中傳回的是條件比對不成功的自動化配置

通路:

<a href="https://s2.51cto.com/wyfs02/M00/A6/77/wKioL1nPUNfBT8VcAACEY9j-_Cw026.png" target="_blank"></a>

必須給予特定權限才能通路資源!解決方案:關閉安全認證!

management.security.enabled=false

<a href="https://s5.51cto.com/wyfs02/M00/A6/77/wKioL1nPUOSD02MoAAF_TvknYlI224.png" target="_blank"></a>

從如上示例中我們可以看到,每個自動化配置候選項中都有一系列的條件,比如上面沒有成功比對的

HealthIndicatorAutoConfiguration.DataSourcesHealthIndicatorConfiguration配置,它的先決條件就是需要在工程中包含

org.springframework.jdbc.core.JdbcTemplate類,由于我們沒有引入相關的依賴,它就不會執行自動化配置内容。是以,當我們發現有一些期望的配置沒有生效時,就可以通過該端點來檢視沒有生效的具體原因。

/beans:該端點用來擷取應用上下文中建立的所有Bean。

<a href="https://s2.51cto.com/wyfs02/M01/A6/77/wKioL1nPUPbh6aukAAA5gGYJsqk057.png" target="_blank"></a>

如上示例中,我們可以看到在每個bean中都包含了下面這幾個資訊:

bean:Bean的名稱

scope:Bean的作用域

type:Bean的Java類型

reource:class檔案的具體路徑

dependencies:依賴的Bean名稱

/configprops:該端點用來擷取應用中配置的屬性資訊報告。從下面該端點傳回示例的片段中,我們看到傳回了關于該短信的配置資訊,prefix屬性代表了屬性的配置字首,properties代表了各個屬性的名稱和值。是以,我們可以通過該報告來看到各個屬性的配置路徑,比如我們要關閉該端點,就可以通過使用endpoints.configprops.enabled=false來完成設定。

<a href="https://s1.51cto.com/wyfs02/M02/07/C5/wKiom1nPUUTirDkEAAE2mDMfCzI189.png" target="_blank"></a>

設定:endpoints.configprops.enabled=false

<a href="https://s4.51cto.com/wyfs02/M01/07/C5/wKiom1nPUU2iK-YSAAB_ef0c3F0582.png" target="_blank"></a>

/env:該端點與/configprops不同,它用來擷取應用所有可用的環境屬性報告。包括:環境變量、JVM屬性、應用的配置配置、指令行中的參數。從下面該端點傳回的示例片段中,我們可以看到它不僅傳回了應用的配置屬性,還傳回了系統屬性、環境變量等豐富的配置資訊,其中也包括了應用還沒有沒有使用的配置。是以它可以幫助我們友善地看到目前應用可以加載的配置資訊,并配合@ConfigurationProperties注解将它們引入到我們的應用程式中來進行使用。另外,為了配置屬性的安全,對于一些類似密碼等敏感資訊,該端點都會進行隐私保護,但是我們需要讓屬性名中包含:password、secret、key這些關鍵詞,這樣該端點在傳回它們的時候會使用*來替代實際的屬性值。

<a href="https://s1.51cto.com/wyfs02/M00/A6/77/wKioL1nPUROiAXixAAB1ODEmwhg616.png" target="_blank"></a>

/mappings:該端點用來傳回所有Spring MVC的控制器映射關系報告。從下面的示例片段中,我們可以看該報告的資訊與我們在啟用Spring MVC的Web應用時輸出的日志資訊類似,其中bean屬性辨別了該映射關系的請求處理器,method屬性辨別了該映射關系的具體處理類和處理函數。

<a href="https://s2.51cto.com/wyfs02/M00/07/C5/wKiom1nPUZji5fx8AABVFPCeYug450.png" target="_blank"></a>

/info:該端點用來傳回一些應用自定義的資訊。預設情況下,該端點隻會傳回一個空的json内容。我們可以在application.properties配置檔案中通過info字首來設定一些屬性,需要在配置檔案設定:

application.yml配置:

info:

 aaa:

    name: xxx

    email: [email protected]

 bbb:

    age: 25

    hobbies: running

 build:

    artifact: "@project.artifactId@"

    name: "@project.name@"

version: "@project.version@"

application.properties配置:

# actuator中/info資訊自定義配置

info.aaa.name=wyait

[email protected]

info.bbb.age=27

info.bbb.hobbies=running

info.build.artifact="@project.artifactId@"

info.build.name="@project.name@"

info.build.version="@project.version@"

<a href="https://s2.51cto.com/wyfs02/M00/A6/77/wKioL1nPUWChM3QBAAEvr8Jjk34217.png" target="_blank"></a>

如果使用maven,可以通路pom.xml檔案的資訊,用法如下:

// 擷取pom.xml中project節點下artifactId屬性

artifact: “@project.artifactId@”

上面我們所介紹的應用配置類端點所提供的資訊報告在應用啟動的時候都已經基本确定了其傳回内容,可以說是一個靜态報告。而度量名額類端點提供的報告内容則是動态變化的,這些端點提供了應用程式在運作過程中的一些快照資訊,比如:記憶體使用情況、HTTP請求統計、外部資源名額等。這些端點對于我們建構微服務架構中的監控系統非常有幫助,由于Spring Boot應用自身實作了這些端點,是以我們可以很友善地利用它們來收集我們想要的資訊,以制定出各種自動化政策。下面,我們就來分别看看這些強大的端點功能。

·        /metrics:該端點用來傳回目前應用的各類重要度量名額,比如:記憶體資訊、線程資訊、垃圾回收資訊等。

{

mem: 406912

mem.free: 265320

processors: 4

instance.uptime: 266897

uptime: 271256

systemload.average: -1

heap.committed: 366080

heap.init: 130221

heap.used: 100759

heap: 1853440

nonheap.committed: 41088

nonheap.init: 24000

nonheap.used: 40832

nonheap: 133120

threads.peak: 24

threads.daemon: 20

threads.totalStarted: 27

threads: 22

classes: 6639

classes.loaded: 6639

classes.unloaded: 0

gc.ps_scavenge.count: 8

gc.ps_scavenge.time: 77

gc.ps_marksweep.count: 0

gc.ps_marksweep.time: 0

httpsessions.max: -1

httpsessions.active: 0

counter.status.200.env: 1

counter.status.200.mappings: 1

gauge.response.env: 67

gauge.response.mappings: 5

}

從上面的示例中,我們看到有這些重要的路徑成本:

系統資訊:包括處理器數量processors、運作時間uptime和instance.uptime、系統平均負載systemload.average。

mem.*:記憶體概要資訊,包括配置設定給應用的總記憶體數量以及目前空閑的記憶體數量。這些資訊來自java.lang.Runtime。

heap.*:堆記憶體使用情況。這些資訊來自java.lang.management.MemoryMXBean接口中getHeapMemoryUsage方法擷取的java.lang.management.MemoryUsage。

nonheap.*:非堆記憶體使用情況。這些資訊來自java.lang.management.MemoryMXBean接口中getNonHeapMemoryUsage方法擷取的java.lang.management.MemoryUsage。

threads.*:線程使用情況,包括線程數、守護線程數(daemon)、線程峰值(peak)等,這些資料均來自java.lang.management.ThreadMXBean。

classes.*:應用加載和解除安裝的類統計。這些資料均來自java.lang.management.ClassLoadingMXBean。

gc.*:垃圾收集器的詳細資訊,包括垃圾回收次數gc.ps_scavenge.count、垃圾回收消耗時間gc.ps_scavenge.time、标記-清除算法的次數gc.ps_marksweep.count、标記-清除算法的消耗時間gc.ps_marksweep.time。這些資料均來自java.lang.management.GarbageCollectorMXBean。

httpsessions.*:Tomcat容器的會話使用情況。包括最大會話數httpsessions.max和活躍會話數httpsessions.active。該度量名額資訊僅在引入了嵌入式Tomcat作為應用容器的時候才會提供。

gauge.*:HTTP請求的性能名額之一,它主要用來反映一個絕對數值。比如上面示例中的gauge.response.hello: 5,它表示上一次hello請求的延遲時間為5毫秒。

counter.*:HTTP請求的性能名額之一,它主要作為計數器來使用,記錄了增加量和減少量。如上示例中counter.status.200.hello: 11,它代表了hello請求傳回200狀态的次數為11。

另一種描述:此處我們可以看到基本的 memory , heap ,class loading , processor 和thread pool 資訊,連同一些HTTP名額。在該執行個體 

中,可以使用 /metrics/{name:.*} 通路單個屬性。

系統記憶體總量(mem),機關:Kb

空閑記憶體數量(mem.free),機關:Kb

處理器數量(processors)

系統正常運作時間(uptime),機關:毫秒

應用上下文(就是一個應用執行個體)正常運作時間(instance.uptime),機關:毫秒

系統平均負載(systemload.average)

堆資訊(heap,heap.committed,heap.init,heap.used),機關:Kb

線程資訊(threads,thread.peak,thead.daemon)

類加載資訊(classes,classes.loaded,classes.unloaded)

垃圾收集資訊(gc.xxx.count,     gc.xxx.time)

最大連接配接數(datasource.xxx.max)

最小連接配接數(datasource.xxx.min)

活動連接配接數(datasource.xxx.active)

連接配接池的使用情況(datasource.xxx.usage)

對于gauge.*和counter.*的統計,這裡有一個特殊的内容請求star-star,它代表了對靜态資源的通路。這兩類度量名額非常有用,我們不僅可以使用它預設的統計名額,還可以在程式中輕松的增加自定義統計值。隻需要通過注入org.springframework.boot.actuate.metrics.CounterService和org.springframework.boot.actuate.metrics.GaugeService來實作自定義的統計名額資訊。

添加自定義metrics

需要将CounterService或者GaugeService注入到你的bean裡面,CounterService提供了三個方法:

increment:将指定的計數器增加1。

decrement:将指定的計數器減1。

reset:複位指定的計數器。

就像這樣子:   

@Service

public class UserService {

    @Autowired

    UserMapper mapper;

    CounterService counterService;

    GaugeService gaugeService;

    public Map&lt;object, object&gt;findById(String id) {

       counterService.increment("services.system.userService.findById.invoked");

        return mapper.findById(id);

    }

然後在/metrics接口裡面就可以看到自定義的資訊了!

/metrics端點可以提供應用運作狀态的完整度量名額報告,這項功能非常的實用,但是對于監控系統中的各項監控功能,它們的監控内容、資料收集頻率都有所不同,如果我們每次都通過全量擷取報告的方式來收集,略顯粗暴。是以,我們還可以通過/metrics/{name}接口來更細粒度的擷取度量資訊,比如我們可以通過通路/metrics/mem.free來擷取目前可用記憶體數量。

/health:該端點在一開始的示例中我們已經使用過了,它用來擷取應用的各類健康名額資訊。在spring-boot-starter-actuator子產品中自帶實作了一些常用資源的健康名額檢測器。

這些檢測器都通過HealthIndicator接口實作,并且會根據依賴關系的引入實作自動化裝配,比如用于檢測磁盤的DiskSpaceHealthIndicator、檢測DataSource連接配接是否可用的DataSourceHealthIndicator等。

有時候,我們可能還會用到一些Spring Boot的Starter POMs中還沒有封裝的産品來進行開發,

比如:當使用RocketMQ作為消息代理時,由于沒有自動化配置的檢測器,是以我們需要自己來實作一個用來采集健康資訊的檢測器。比如,我們可以在Spring Boot的應用中,為org.springframework.boot.actuate.health.HealthIndicator接口實作一個對RocketMQ的檢測器類:

@Component

public classRocketMQHealthIndicator implements HealthIndicator {

    @Override

    public Health health() {

        int errorCode = check();

        if (errorCode != 0) {

          returnHealth.down().withDetail("Error Code", errorCode).build();

        }

        return Health.up().build();

 private int check() {

       // 對監控對象的檢測操作

 }

通過重寫health()函數來實作健康檢查,傳回的Heath對象中,共有兩項内容,一個是狀态資訊,除了該示例中的UP與DOWN之外,還有UNKNOWN和OUT_OF_SERVICE,可以根據需要來實作傳回;

還有一個詳細資訊,采用Map的方式存儲,在這裡通過withDetail函數,注入了一個Error Code資訊,我們也可以填入一下其他資訊,比如,檢測對象的IP位址、端口等。重新啟動應用,并通路/health接口,我們在傳回的JSON字元串中,将會包含了如下資訊:

"rocketMQ": {

 "status": "UP"

自定義health

·        下面的HealthIndicators會被Spring Boot自動配置

名稱

描述

CassandraHealthIndicator

檢查Cassandra是否可用

DiskSpaceHealthIndicator

檢查磁盤空間是否不足

DataSourceHealthIndicator

檢查能否從DataSource擷取連結

ElasticsearchHealthIndicator

檢查Elasticsearch cluste是否可用

JmsHealthIndicator

檢查JMS broker是否可用

MailHealthIndicator

檢查mail server是否可用

MongoHealthIndicator

檢查Mongo database是否可用

RabbitHealthIndicator

檢查Rabbit server是否可用

RedisHealthIndicator

檢查Redis server是否可用

SolrHealthIndicator

檢查Solr server是否可用

我們可以通過實作<code>HealthIndicator</code>接口,編寫自己的<code>/health</code>方法邏輯。也可以增加自定義監控方法。

想自定義健康資訊,可以注冊實作了HealthIndicator接口的Spring beans。你需要提供一個health()方法的實作,并傳回一個Health響應。Health響應需要包含一個status和可選的用于展示的詳情。

importorg.springframework.boot.actuate.health.Health;

importorg.springframework.boot.actuate.health.HealthIndicator;

importorg.springframework.stereotype.Component;

public class MyHealthIndicatorimplements HealthIndicator {

        int errorCode = check(); // performsome specific health check

            returnHealth.down().withDetail("Error Code", errorCode).build();

/dump:該端點用來暴露程式運作中的線程資訊。它使用java.lang.management.ThreadMXBean的dumpAllThreads方法來傳回所有含有同步資訊的活動線程詳情。

<a href="https://s3.51cto.com/wyfs02/M01/07/C5/wKiom1nPUbCSRouSAAAlDZe_5us193.png" target="_blank"></a>

/trace:該端點用來傳回基本的HTTP跟蹤資訊。預設情況下,跟蹤資訊的存儲采用org.springframework.boot.actuate.trace.InMemoryTraceRepository實作的記憶體方式,始終保留最近的100條請求記錄。它記錄的内容格式如下:

<a href="https://s4.51cto.com/wyfs02/M00/07/C5/wKiom1nPUbjzkXmoAAA3H-B_Dog880.png" target="_blank"></a>

仔細的讀者可能會發現,我們在“初識Actuator”時運作示例的控制台中輸出的所有監控端點,已經在介紹應用配置類端點和度量名額類端點時都說明完了。那麼還有哪些是操作控制類端點呢?實際上,由于之前介紹的所有端點都是用來反映應用自身的屬性或是運作中的狀态,相對于操作控制類端點沒有那麼敏感,是以他們預設都是啟用的。而操作控制類端點擁有更強大的控制能力,如果要使用它們的話,需要通過屬性來配置開啟。

在原生端點中,隻提供了一個用來關閉應用的端點:<code>/shutdown</code>。我們可以通過如下配置開啟它:

endpoints.shutdown.enabled=true

在配置了上述屬性之後,隻需要通路該應用的/shutdown端點就能實作關閉該應用的遠端操作。由于開放關閉應用的操作本身是一件非常危險的事,是以真正線上上使用的時候,我們需要對其加入一定的保護機制,比如:定制Actuator的端點路徑、整合SpringSecurity進行安全校驗等。

位址和端口的配置

<code>management.port</code>:指定通路這些監控方法的端口,與邏輯接口端口分離。如果不想将這些暴露在http中,可以設定management.port = -1

<code>management.address</code>:指定位址,比如隻能通過本機監控,可以設定     management.address = 127.0.0.1

敏感資訊通路限制

根據上面表格,鑒權為<code>false</code>的,表示不敏感,可以随意通路,否則就是做了一些保護,不能随意通路。

endpoints.mappings.sensitive=false

解決方案:關閉spring security認證!

這樣需要對每一個都設定,比較麻煩。敏感方法預設是需要使用者擁有<code>ACTUATOR</code>角色,是以,也可以設定關閉安全限制:

或者配合<code>Spring Security</code>做細粒度控制。

本文轉自 wyait 51CTO部落格,原文連結:http://blog.51cto.com/wyait/1970021,如需轉載請自行聯系原作者