您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關如何在Spring Boot中使用 Actuator實現一個監控端點功能,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
在Spring Boot的眾多Starter POMs中有一個特殊的模塊,它不同于其他模塊那樣大多用于開發業務功能或是連接一些其他外部資源。它完全是一個用于暴露自身信息的模塊,所以很明顯,它的主要作用是用于監控與管理,它就是:spring-boot-starter-actuator
。
spring-boot-starter-actuator
模塊的實現對于實施微服務的中小團隊來說,可以有效地減少監控系統在采集應用指標時的開發量。當然,它也并不是萬能的,有時候我們也需要對其做一些簡單的擴展來幫助我們實現自身系統個性化的監控需求。下面,在本文中,我們將詳解的介紹一些關于spring-boot-starter-actuator
模塊的內容,包括它的原生提供的端點以及一些常用的擴展和配置方式。
初識Actuator
下面,我們可以通過對快速入門中實現的Spring Boot應用增加spring-boot-starter-actuator
模塊功能,來對它有一個直觀的認識。
在現有的Spring Boot應用中引入該模塊非常簡單,只需要在pom.xml
的dependencies節點中,新增spring-boot-starter-actuator的依賴即可,具體如下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
通過增加該依賴之后,重新啟動應用。此時,我們可以在控制臺中看到如下圖所示的輸出:
上圖顯示了一批端點定義,這些端點并非我們自己在程序中創建,而是由spring-boot-starter-actuator
模塊根據應用依賴和配置自動創建出來的監控和管理端點。通過這些端點,我們可以實時的獲取應用的各項監控指標,比如:訪問/health端點,我們可以獲得如下返回的應用健康信息:
{ "status": "UP", "diskSpace": { "status": "UP", "total": 491270434816, "free": 383870214144, "threshold": 10485760 } }
原生端點
通過在快速入門示例中添加spring-boot-starter-actuator
模塊,我們已經對它有了一個初步的認識。接下來,我們詳細介紹一下spring-boot-starter-actuator
模塊中已經實現的一些原生端點。如果根據端點的作用來說,我們可以原生端點分為三大類:
下面我們來詳細了解一下這三類端點都分別可以為我們提供怎么樣的有用信息和強大功能,以及我們如何去擴展和配置它們。
應用配置類
由于Spring Boot為了改善傳統Spring應用繁雜的配置內容,采用了包掃描和自動化配置的機制來加載原本集中于xml文件中的各項內容。雖然這樣的做法,讓我們的代碼變得非常簡潔,但是整個應用的實例創建和依賴關系等信息都被離散到了各個配置類的注解上,這使得我們分析整個應用中資源和實例的各種關系變得非常的困難。而這類端點就可以幫助我們輕松的獲取一系列關于Spring 應用配置內容的詳細報告,比如:自動化配置的報告、Bean創建的報告、環境屬性的報告等。
{ "positiveMatches": { // 條件匹配成功的 "EndpointWebMvcAutoConfiguration": [ { "condition": "OnClassCondition", "message": "@ConditionalOnClass classes found: javax.servlet.Servlet,org.springframework.web.servlet.DispatcherServlet" }, { "condition": "OnWebApplicationCondition", "message": "found web application StandardServletEnvironment" } ], ... }, "negativeMatches": { // 條件不匹配成功的 "HealthIndicatorAutoConfiguration.DataSourcesHealthIndicatorConfiguration": [ { "condition": "OnClassCondition", "message": "required @ConditionalOnClass classes not found: org.springframework.jdbc.core.JdbcTemplate" } ], ... } }
從如上示例中我們可以看到,每個自動化配置候選項中都有一系列的條件,比如上面沒有成功匹配的HealthIndicatorAutoConfiguration.DataSourcesHealthIndicatorConfiguration
配置,它的先決條件就是需要在工程中包含org.springframework.jdbc.core.JdbcTemplate
類,由于我們沒有引入相關的依賴,它就不會執行自動化配置內容。所以,當我們發現有一些期望的配置沒有生效時,就可以通過該端點來查看沒有生效的具體原因。
[ { "context": "hello:dev:8881", "parent": null, "beans": [ { "bean": "org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration$DispatcherServletConfiguration", "scope": "singleton", "type": "org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration$DispatcherServletConfiguration$$EnhancerBySpringCGLIB$$3440282b", "resource": "null", "dependencies": [ "serverProperties", "spring.mvc.CONFIGURATION_PROPERTIES", "multipartConfigElement" ] }, { "bean": "dispatcherServlet", "scope": "singleton", "type": "org.springframework.web.servlet.DispatcherServlet", "resource": "class path resource [org/springframework/boot/autoconfigure/web/DispatcherServletAutoConfiguration$DispatcherServletConfiguration.class]", "dependencies": [] } ] } ]
如上示例中,我們可以看到在每個bean中都包含了下面這幾個信息:
/configprops:該端點用來獲取應用中配置的屬性信息報告。從下面該端點返回示例的片段中,我們看到返回了關于該短信的配置信息,prefix屬性代表了屬性的配置前綴,properties
代表了各個屬性的名稱和值。所以,我們可以通過該報告來看到各個屬性的配置路徑,比如我們要關閉該端點,就可以通過使用endpoints.configprops.enabled=false
來完成設置。
{ "configurationPropertiesReportEndpoint": { "prefix": "endpoints.configprops", "properties": { "id": "configprops", "sensitive": true, "enabled": true } }, ... }
/env:該端點與/configprops
不同,它用來獲取應用所有可用的環境屬性報告。包括:環境變量、JVM屬性、應用的配置配置、命令行中的參數。從下面該端點返回的示例片段中,我們可以看到它不僅返回了應用的配置屬性,還返回了系統屬性、環境變量等豐富的配置信息,其中也包括了應用還沒有沒有使用的配置。所以它可以幫助我們方便地看到當前應用可以加載的配置信息,并配合@ConfigurationProperties
注解將它們引入到我們的應用程序中來進行使用。另外,為了配置屬性的安全,對于一些類似密碼等敏感信息,該端點都會進行隱私保護,但是我們需要讓屬性名中包含:password、secret、key這些關鍵詞,這樣該端點在返回它們的時候會使用*來替代實際的屬性值。
{ "profiles": [ "dev" ], "server.ports": { "local.server.port": 8881 }, "servletContextInitParams": { }, "systemProperties": { "idea.version": "2016.1.3", "java.runtime.name": "Java(TM) SE Runtime Environment", "sun.boot.library.path": "C:\\Program Files\\Java\\jdk1.8.0_91\\jre\\bin", "java.vm.version": "25.91-b15", "java.vm.vendor": "Oracle Corporation", ... }, "systemEnvironment": { "configsetroot": "C:\\WINDOWS\\ConfigSetRoot", "RABBITMQ_BASE": "E:\\tools\\rabbitmq", ... }, "applicationConfig: [classpath:/application-dev.properties]": { "server.port": "8881" }, "applicationConfig: [classpath:/application.properties]": { "server.port": "8885", "spring.profiles.active": "dev", "info.app.name": "spring-boot-hello", "info.app.version": "v1.0.0", "spring.application.name": "hello" } }
/mappings:該端點用來返回所有Spring MVC的控制器映射關系報告。從下面的示例片段中,我們可以看該報告的信息與我們在啟用Spring MVC的Web應用時輸出的日志信息類似,其中bean
屬性標識了該映射關系的請求處理器,method
屬性標識了該映射關系的具體處理類和處理函數。
{ "/webjars/**": { "bean": "resourceHandlerMapping" }, "/**": { "bean": "resourceHandlerMapping" }, "/**/favicon.ico": { "bean": "faviconHandlerMapping" }, "{[/hello]}": { "bean": "requestMappingHandlerMapping", "method": "public java.lang.String com.didispace.web.HelloController.index()" }, "{[/mappings || /mappings.json],methods=[GET],produces=[application/json]}": { "bean": "endpointHandlerMapping", "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()" }, ... }
/info:該端點用來返回一些應用自定義的信息。默認情況下,該端點只會返回一個空的json內容。我們可以在application.properties
配置文件中通過info
前綴來設置一些屬性,比如下面這樣:
info.app.name=spring-boot-hello info.app.version=v1.0.0
再訪問/info端點,我們可以得到下面的返回報告,其中就包含了上面我們在應用自定義的兩個參數。
{ "app": { "name": "spring-boot-hello", "version": "v1.0.0" } }
度量指標類
上面我們所介紹的應用配置類端點所提供的信息報告在應用啟動的時候都已經基本確定了其返回內容,可以說是一個靜態報告。而度量指標類端點提供的報告內容則是動態變化的,這些端點提供了應用程序在運行過程中的一些快照信息,比如:內存使用情況、HTTP請求統計、外部資源指標等。這些端點對于我們構建微服務架構中的監控系統非常有幫助,由于Spring Boot應用自身實現了這些端點,所以我們可以很方便地利用它們來收集我們想要的信息,以制定出各種自動化策略。下面,我們就來分別看看這些強大的端點功能。
/metrics:該端點用來返回當前應用的各類重要度量指標,比如:內存信息、線程信息、垃圾回收信息等。
{ "mem": 541305, "mem.free": 317864, "processors": 8, "instance.uptime": 33376471, "uptime": 33385352, "systemload.average": -1, "heap.committed": 476672, "heap.init": 262144, "heap.used": 158807, "heap": 3701248, "nonheap.committed": 65856, "nonheap.init": 2496, "nonheap.used": 64633, "nonheap": 0, "threads.peak": 22, "threads.daemon": 20, "threads.totalStarted": 26, "threads": 22, "classes": 7669, "classes.loaded": 7669, "classes.unloaded": 0, "gc.ps_scavenge.count": 7, "gc.ps_scavenge.time": 118, "gc.ps_marksweep.count": 2, "gc.ps_marksweep.time": 234, "httpsessions.max": -1, "httpsessions.active": 0, "gauge.response.beans": 55, "gauge.response.env": 10, "gauge.response.hello": 5, "gauge.response.metrics": 4, "gauge.response.configprops": 153, "gauge.response.star-star": 5, "counter.status.200.beans": 1, "counter.status.200.metrics": 3, "counter.status.200.configprops": 1, "counter.status.404.star-star": 2, "counter.status.200.hello": 11, "counter.status.200.env": 1 }
從上面的示例中,我們看到有這些重要的度量值:
對于gauge.*
和counter.*
的統計,這里有一個特殊的內容請求star-star,它代表了對靜態資源的訪問。這兩類度量指標非常有用,我們不僅可以使用它默認的統計指標,還可以在程序中輕松的增加自定義統計值。只需要通過注入org.springframework.boot.actuate.metrics.CounterService和org.springframework.boot.actuate.metrics.GaugeService
來實現自定義的統計指標信息。比如:我們可以像下面這樣自定義實現對hello接口的訪問次數統計。
@RestController public class HelloController { @Autowired private CounterService counterService; @RequestMapping("/hello") public String greet() { counterService.increment("didispace.hello.count"); return ""; } }
/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 class RocketMQHealthIndicator implements HealthIndicator { @Override public Health health() { int errorCode = check(); if (errorCode != 0) { return Health.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" }
/dump:該端點用來暴露程序運行中的線程信息。它使用java.lang.management.ThreadMXBean的dumpAllThreads
方法來返回所有含有同步信息的活動線程詳情。
/trace:該端點用來返回基本的HTTP跟蹤信息。默認情況下,跟蹤信息的存儲采用org.springframework.boot.actuate.trace.InMemoryTraceRepository
實現的內存方式,始終保留最近的100條請求記錄。它記錄的內容格式如下:
[ { "timestamp": 1482570022463, "info": { "method": "GET", "path": "/metrics/mem", "headers": { "request": { "host": "localhost:8881", "connection": "keep-alive", "cache-control": "no-cache", "user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36", "postman-token": "9817ea4d-ad9d-b2fc-7685-9dff1a1bc193", "accept": "*/*", "accept-encoding": "gzip, deflate, sdch", "accept-language": "zh-CN,zh;q=0.8" }, "response": { "X-Application-Context": "hello:dev:8881", "Content-Type": "application/json;charset=UTF-8", "Transfer-Encoding": "chunked", "Date": "Sat, 24 Dec 2016 09:00:22 GMT", "status": "200" } } } }, ... ]
操作控制類
仔細的讀者可能會發現,我們在“初識Actuator”時運行示例的控制臺中輸出的所有監控端點,已經在介紹應用配置類端點和度量指標類端點時都講解完了。那么還有哪些是操作控制類端點呢?實際上,由于之前介紹的所有端點都是用來反映應用自身的屬性或是運行中的狀態,相對于操作控制類端點沒有那么敏感,所以他們默認都是啟用的。而操作控制類端點擁有更強大的控制能力,如果要使用它們的話,需要通過屬性來配置開啟。
在原生端點中,只提供了一個用來關閉應用的端點:/shutdown。我們可以通過如下配置開啟它:
endpoints.shutdown.enabled=true
在配置了上述屬性之后,只需要訪問該應用的/shutdown端點就能實現關閉該應用的遠程操作。由于開放關閉應用的操作本身是一件非常危險的事,所以真正在線上使用的時候,我們需要對其加入一定的保護機制,比如:定制Actuator的端點路徑、整合Spring Security進行安全校驗等。
關于如何在Spring Boot中使用 Actuator實現一個監控端點功能就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。