天天看點

Spring Boot Actuator入門簡介

微服務與監控

微服務應用采用分布式部署方式,大部分應用都是運作在不同的機器上,彼此通過http等方式進行互動,前背景的業務流會經過很多個微服務的處理和傳遞,出現異常如何快速定位是哪個環節出現問題,這是微服務架構不得不面對和解決的一個問題。這就是應用監控。

微服務應用監控是一個很大的話題,本文試圖加以總結。

監控什麼-what

服務概要資訊、服務健康名額、服務請求映射、服務調用鍊、服務API監控、服務内部元件狀态、服務性能名額;

  • 對于一個微服務,需要監控的資訊很多,每個微服務是一個微型獨立的服務,麻雀雖小,五髒俱全,從UI到DB;
  • 而一個複雜的系統可能涉及到上百個服務節點部署,是以掌控一個微服務的健康名額、環境配置、服務配置、請求映射、spring bean、請求trace資訊、日志資訊,Rest API服務是相當有必要的;
  • 作為應用管理人員,可以通過監控平台檢視各個節點執行個體的運作狀态,包括資料庫連接配接資訊、服務調用、邏輯流或者頁面流的調用情況及執行時長;
  • 作為開發人員,可以檢視自己的節點執行個體在運作期的所有資訊,Spring bean是否正常加載、yml配置是否起效,如何修改等;
  • 作為運維人員,可以通過平台檢視各個服務節點的日志,而不用從分散各地的伺服器拉取日志,檢視系統CPU、記憶體、堆棧等資訊

監控政策-how

如何監控微服務呢?主要基于四種手段來監控:

  • Actuator
  • JMX
  • Spring admin
  • Swagger
  • actuator
  • admin
  • hystrix dashboard
  • 分布式調用鍊

Spring Boot Actuator

簡介

Spring Boot Actuator,即maven依賴為spring-boot-starter-actuator的子產品,是Spring Boot的提供的衆多Starter之一。是一個用于暴露自身資訊的子產品,其主要作用是用于監控與管理。

spring-boot-starter-actuator子產品的實作對于實施微服務的中小團隊來說,可以有效地減少監控系統在采集應用名額時的開發量。當然,它也并不是萬能的,有時候也需要對其做一些簡單的擴充,以實作自身系統個性化的監控需求。

入門使用

在已有的Spring boot應用中添加依賴:spring-boot-starter-actuator和spring-boot-starter-security,具體來說,在pom.xml檔案添加:

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

即可在預設的服務以及端口檢視監控資訊,比如:http://localhost:8080/health, 會得到一串JSON字元串,表征目前系統的監控狀況。加入security是為了保證actuator暴露的監控接口的安全性,通路應用監控端點時,都需要輸入驗證資訊。本地的測試demo應用,Security依賴可以選擇不加,即不需要引入安全管理,但生産環境不能這麼做。

常用端點

Spring boot actuator自帶很多預設的endpoint,如下:

端點 描述 HTTP方法
autoconfig 顯示自動配置的資訊 GET
beans 顯示應用程式上下文所有的Spring bean GET
configprops 顯示所有@ConfigurationProperties的配置屬性清單 GET
dump 顯示線程活動的快照 GET
env 顯示應用的環境變量 GET
env/{name} 根據名稱擷取顯示特定的環境變量 GET
health 顯示應用程式的健康名額,這些值由HealthIndicator的實作類提供。常見取值:UP DOWN UNKNOWN OUTOFSERVICE GET
info 顯示應用的資訊,可使用 info.*屬性自定義info端點公開的資料 GET
mappings 顯示所有的URL路徑 GET
metrics 顯示應用的度量标準資訊 GET
metrics/{name} 根據指定的名稱擷取應用的度量标準資訊 GET
shutdown 關閉應用(預設情況下不啟用,如需啟用,需設定endpoints.shutdown.enabled=true) POST
trace 提供HTTP請求跟蹤資訊(時間戳、HTTP頭等,預設情況下為最近100個HTTP請求) GET

分類

Actuator監控分成兩類:原生端點和使用者自定義端點;自定義端點主要是指擴充性,使用者可以根據自己的實際應用,定義一些比較關心的名額,在運作期進行監控。

上面的端點,根據端點的作用來說,可以原生端點分為三大類:

  1. 應用配置類:應用在運作期的靜态資訊,例如:自動配置資訊、加載的spring bean資訊、yml檔案配置資訊、環境資訊、請求映射資訊;
  2. 度量名額類:擷取應用程式運作過程中用于監控的度量名額,比如:記憶體資訊、線程池資訊、HTTP請求統計、堆棧、請求連接配接數、健康名額、metrics資訊等。
  3. 操作控制類:主要是指shutdown,提供對應用的關閉等操作類功能。

應用配置類

給出靜态報告,因為這類應用配置端點所提供的資訊報告在應用啟動的時候都已經基本确定其傳回内容。借助于這類端點,可以輕松擷取一系列關于Spring 應用配置内容的詳細報告,比如:自動化配置的報告、Bean建立的報告、環境屬性的報告等。

/info

用來傳回一些應用自定義的資訊,以info開頭的配置資訊。預設情況下隻傳回一個空的json内容。在application.properties中通過info字首來設定屬性:

# 示例設定
info.app.name=spring-boot-actuator-silly-demo
info.app.version=v1.0.0
info.app.author=johnny      

此後再通路/info端點,就不是預設的空的JSON字元串,而是包含上面自定義的資訊。

/mappings

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

{
    "/webjars/**": {
        "bean": "resourceHandlerMapping"
    },
    "/**": {
        "bean": "resourceHandlerMapping"
    },
    "/**/favicon.ico": {
        "bean": "faviconHandlerMapping"
    }
}      
/autoconfig

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

/beans

該端點用來擷取應用上下文中建立的所有Bean。每個bean中都包含以下資訊:

bean:Bean的名稱

scope:Bean的作用域

type:Bean的Java類型

reource:class檔案的具體路徑

dependencies:依賴的Bean名稱

/configprops

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

/env

與/configprops不同(configprops關注于配置資訊),/env關注運作環境資訊,用來擷取應用所有可用的環境屬性報告。包括:環境變量、JVM屬性、應用的配置配置、指令行中的參數,包括應用還沒有沒有使用的配置。可友善地看到目前應用可以加載的配置資訊,并配合@ConfigurationProperties注解将它們引入到我們的應用程式中來進行使用。為了避免敏感資訊暴露到 /env 裡,所有名為password、secret、key(或者名字中最後一段是這些)的屬性在 /env 裡都會加上*。

度量名額類

給出動态報告,因為提供應用程式在運作過程中的一些快照資訊,比如:記憶體使用情況、HTTP請求統計、外部資源名額等。

/metrics

最重要的監控端點,提供應用運作狀态的完整度量名額報告,主要包括:記憶體資訊、線程資訊、垃圾回收資訊、類加載資訊等。對于生産級别的應用,資料量可能比較大。對于監控系統中的各項監控功能,它們的監控内容、資料收集頻率都有所不同,如果每次都通過全量擷取報告的方式來收集,略顯粗暴。故而可以通過/metrics/{name}接口來擷取細粒度的度量資訊,比如通過通路/metrics/mem.free來擷取目前可用記憶體數量。

傳回JSON資料類似于(縮減版):

{
  "counter.status.404.star-star": 2,
  "nonheap.init": 2496,
  "httpsessions.max": -1,
  "httpsessions.active": 0
}      

這些資料資訊來自于包java.lang.management.*下面的接口的(方法)。httpsessions,Tomcat容器的會話使用情況,包括最大會話數httpsessions.max和活躍會話數httpsessions.active。該度量名額資訊僅在引入了嵌入式Tomcat作為應用容器的時候才會提供。

對 /metrics接口提供的資訊進行簡單分類如下表:

分類 字首 報告内容
垃圾收集器 gc.* 已經發生過的垃圾收集次數,以及垃圾收集所耗費的時間,适用于标記-清理垃圾收集器和并行垃圾收集器,資料源自java.lang.management.GarbageCollectorMXBean(後面省略包名)
記憶體 mem.* 配置設定給應用程式的記憶體數量和空閑的記憶體數量,資料源自Runtime
heap.* 目前記憶體用量,資料源自MemoryUsage
類加載器 classes.* JVM類加載器加載與解除安裝的類的數量,資料源自ClassLoadingMXBean
系統 processors、instance.uptime、uptime、systemload.average 系統資訊,例如處理器數量資料源自Runtime、運作時間資料源自RuntimeMXBean、平均負載資料源自OperatingSystemMXBean
線程池 thread.* 線程、守護線程的數量,以及JVM啟動後的線程數量峰值,資料源自ThreadMXBean
資料源 datasource.* 資料源連接配接的數量,源自資料源的中繼資料,僅當Spring應用程式上下文裡存在 DataSource Bean 的時候才會有這個資訊
Tomcat 會話 httpsessions.* Tomcat的活躍會話數和最大會話數,資料源自嵌入式Tomcat的Bean,僅在使用嵌入式Tomcat伺服器運作應用程式時才有這個資訊)
HTTP counter.status.、gauge.response. 多種應用程式服務HTTP請求的路徑成本與計數器

一些路徑成本,比如資料源和Tomcat會話,僅在應用程式中運作特定元件時才有資料。你還可以注冊自己的度量資訊。

HTTP的計數器和路徑成本需要做一點說明。counter.status 後的值是HTTP狀态碼,随後是所請求的路徑。舉個例子,counter.status.200.metrics 表明/metrics端點傳回 200(OK) 狀态碼的次數。

HTTP的度量資訊在結構上也差不多,卻在報告另一類資訊。它們全部以gauge.response 開頭,,表明這是HTTP響應的度量資訊。字首後是對應的路徑。路徑成本是以毫秒為機關的時間,反映最近處理該路徑請求的耗時。

root路徑指向的是根路徑或/。star-star代表那些Spring 認為是靜态資源的路徑,包括圖檔、js和css,其中還包含那些找不到的資源。這就是為什麼你經常會看到 counter.status.404.star-star,這是傳回404 (NOT FOUND)狀态的請求數。  

/metrics接口會傳回所有的可用路徑成本,要擷取單個值,請求時可以在URL後加上對應的鍵名。

/dump

生成目前線程活動的快照,友善在日常定位問題時檢視線程的情況,主要展示線程名、線程ID、線程的狀态、是否等待鎖資源等資訊。使用ThreadMXBean的dumpAllThreads方法來傳回所有含有同步資訊的活動線程詳情。

/trace

該端點用來傳回基本的HTTP跟蹤資訊,包括請求方法、路徑、時間戳以及請求和響應的頭資訊,記錄每一次請求的詳細資訊。預設情況下,跟蹤資訊的存儲采用InMemoryTraceRepository實作的記憶體方式,始終保留最近的100條請求記錄。

/health

用來擷取應用的各類健康名額資訊,包含磁盤檢測和資料庫檢測。actuator子產品中自帶實作一些常用資源的健康名額檢測器,通過實作HealthIndicator接口,并且會根據依賴關系的引入實作自動化裝配,比如用于檢測磁盤的DiskSpaceHealthIndicator、檢測DataSource連接配接是否可用的DataSourceHealthIndicator等。

通過重寫health()函數來實作健康檢查,傳回的Heath對象中,共有兩項内容,一個是狀态資訊,除了該示例中的UP與DOWN之外,還有UNKNOWN和OUT_OF_SERVICE,可以根據需要來實作傳回;還有一個詳細資訊,采用Map的方式存儲,在這裡通過withDetail函數,注入一個Error Code資訊,我們也可以填入一下其他資訊,比如,檢測對象的IP位址、端口等。

增加自定義統計值。隻需要通過注入CounterService和GaugeService來實作自定義的統計名額資訊。比如:我們可以像下面這樣自定義實作對hello接口的通路次數統計。

@RestController
public class HelloController {
    @Autowired
    private CounterService counterService;
    @RequestMapping("/hello")
    public String greet() {
        counterService.increment("didispace.hello.count");
        return "";
    }
}      

操作控制類

/shutdown

通過如下配置開啟它:

​​

​endpoints.shutdown.enabled=true​

實際上,由于之前介紹的所有端點都是用來反映應用自身的屬性或是運作中的狀态,相對于操作控制類端點沒有那麼敏感,是以他們預設都是啟用的。而操作控制類端點擁有更強大的控制能力,如果要使用它們的話,需要通過屬性來配置開啟。

在原生端點中,隻提供了一個用來關閉應用的端點:。

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

進階使用

對于敏感路徑:

方法一:

management:
  security:
    enabled: false      

方法二:

添加 spring-boot-starter-security;

并設定通路的密碼,如果不設定,則是一個随機值,在啟動時會列印。

security:
  basic:
    enabled: true
  user:
    name: johnny
    password: awesome      

自定義端點metrics

Spring Boot允許開發人員以編碼的方式提供更豐富名額資訊,通過/metrics端點來通路。counter是以Number類型來展現的名額;gauge是衡量雙精度計算的名額。任何位置都可以注入CounterService或GaugeService。

counterService.increment(“metricName”);

counterService.decrement(“metricName”);

counterService.reset(“metricName”);

gaugeService.submit(“metricName”, 2.5);

敏感資訊通路限制

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

endpoints.mappings.sensitive=false

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

management.security.enabled=false

或者配合Spring Security做細粒度控制。

啟用和禁用接口

預設情況下所有接口(除/shutdown)都啟用。比如要禁用 /dump 接口,則可以設定如下:

​​

​endpoints.dump.enabled = false​

​ 如果隻想打開一兩個端口,可以先禁用全部端口,然後啟用某幾個:

endpoints.enabled = false
endpoints.metrics.enabled = true      

重寫健康檢測

因為項目裡面用到redis叢集,但并不是用spring boot的配置方式,啟動後項目健康檢查老是檢查redis的時候狀态為down,導緻注冊到eureka後項目狀态也是down。

"redis": { 
    "status": "DOWN", 
    "error": "org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool" 
}      

問下能不能設定spring boot不檢查 redis的健康狀态?

解決方法:

@Component("redisHealthIndicator")
public class MyRedisHealthIndicator implements HealthIndicator {

    @Override
    public Health health() {
        return Health.up().build();
    }
}      

實作​

​HealthIndicator​

​​接口中的health方法,直接傳回up狀态。通過​

​@Component​

​注解,讓Spring Boot掃描到該類就能自動的進行加載,并覆寫原來的redis健康檢查實作RedisHealthIndicator。

使用shell連接配接Actuator

Actuator可通過shell的方式連接配接,不過在Spring Boot 1.5後已被廢棄。通過shell連接配接Actuator,需在工程的pom檔案加上依賴spring-boot-starter-remote-shell,啟動SB應用程式,在程式的控制台會輸出連接配接shell的密碼,密碼是随機的,每次都不一樣:

Spring Boot Actuator入門簡介

使用者名是user,端口是2000,固定寫死,連接配接指令:

​ssh user@localhost -p 2000​

​ 輸入啟動應用時列印輸出的随機密碼,

連接配接上shell後,這時可以通過終端檢視Actuator的各個端點。Spring Boot提供了4個特有的shell指令:

  • beans:列出SB應用上下文的Bean
  • endpoint:調用Actuator端口
  • metrics:度量資訊
  • autoconfig:生成自動配置說明報告

Hystrix dashboard

使用Hystrix Dashboard展示Hystrix用于熔斷的各項度量名額,可以友善的檢視服務執行個體的綜合情況,比如:服務調用次數、服務調用延遲等;但是隻能實作對單個服務執行個體的資料展現。多執行個體情況下,可以使用Turbine将這些度量名額資料進行聚合。

分布式調用鍊

繼續閱讀