SpringBoot指標(biāo)監(jiān)控的實(shí)現(xiàn)
一、SpringBoot——Actuator
1.1 快速開始
未來每一個(gè)微服務(wù)在運(yùn)算部署以后,我們都需要對(duì)其進(jìn)行監(jiān)控、追蹤、審計(jì)和控制等等。Springboot就抽取了Actuator場(chǎng)景,使得我們每個(gè)微服務(wù)快速引用即可獲得生產(chǎn)級(jí)別的應(yīng)用監(jiān)控、審計(jì)等功能。
那么,我們要怎么用呢?
首先,導(dǎo)入我們的場(chǎng)景:
<!--指示監(jiān)控--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
導(dǎo)入場(chǎng)景后,我們啟動(dòng)我們的主程序,我們來訪問一下這個(gè)actuator。
他告訴我們我們現(xiàn)在可以訪問的有http://localhost:8080/actuator和http://localhost:8080/actuator/health。
我們來看一下這個(gè)health。(下圖的意思是正常,如果是宕機(jī)狀態(tài)的話,他的值是DOWN)
在上面的網(wǎng)址:http://localhost:8080/actuator/health 中,actuator后的health是actuator模塊的一個(gè)端點(diǎn)。類似的端點(diǎn)還有很多,借用一下官網(wǎng)的表吧:
端點(diǎn) | 描述 |
---|---|
auditevents | 公開當(dāng)前應(yīng)用程序的審計(jì)事件信息。需要一個(gè)AuditEventRepository豆子。 |
beans | 顯示應(yīng)用程序中所有 Spring bean 的完整列表。 |
caches | 公開可用的緩存。 |
conditions | 顯示在配置和自動(dòng)配置類上評(píng)估的條件以及它們匹配或不匹配的原因。 |
configprops | 顯示所有 的整理列表@ConfigurationProperties。 |
env | 從 Spring 的ConfigurableEnvironment. |
flyway | 顯示已應(yīng)用的任何 Flyway 數(shù)據(jù)庫遷移。需要一顆或多Flyway顆豆子。 |
health | 顯示應(yīng)用程序運(yùn)行狀況信息。 |
httptrace | 顯示 HTTP 跟蹤信息(默認(rèn)情況下,最后 100 個(gè) HTTP 請(qǐng)求-響應(yīng)交換)。需要一個(gè)HttpTraceRepository豆子。 |
info | 顯示任意應(yīng)用程序信息。 |
integrationgraph | 顯示 Spring 集成圖。需要依賴于spring-integration-core. |
loggers | 顯示和修改應(yīng)用程序中記錄器的配置。 |
liquibase | 顯示已應(yīng)用的任何 Liquibase 數(shù)據(jù)庫遷移。需要一顆或多Liquibase顆豆子。 |
metrics | 顯示當(dāng)前應(yīng)用程序的“指標(biāo)”信息。 |
mappings | 顯示所有@RequestMapping路徑的整理列表。 |
quartz | 顯示有關(guān) Quartz 調(diào)度程序作業(yè)的信息。 |
scheduledtasks | 顯示應(yīng)用程序中的計(jì)劃任務(wù)。 |
sessions | 允許從 Spring Session 支持的會(huì)話存儲(chǔ)中檢索和刪除用戶會(huì)話。需要使用 Spring Session 的基于 Servlet 的 Web 應(yīng)用程序。 |
shutdown | 讓應(yīng)用程序正常關(guān)閉。默認(rèn)禁用。 |
startup | 顯示由收集的啟動(dòng)步驟數(shù)據(jù)ApplicationStartup。需要SpringApplication使用BufferingApplicationStartup. |
threaddump | 執(zhí)行線程轉(zhuǎn)儲(chǔ)。 |
注意:雖然我們的Springboot有這么多Actuator的監(jiān)控端點(diǎn),但是,我們剛才也看到了,他默認(rèn)情況下在HTTP就給我們開了一個(gè)health的端點(diǎn)。其他端點(diǎn)默認(rèn)是無法訪問的,得要我們手動(dòng)開啟才行。但是在我們的JMX中默認(rèn)暴露的就是所有的端點(diǎn)了。
什么東西?JMX??JMX是什么?
JMX(Java Management Extensions,即Java管理擴(kuò)展)是一個(gè)為應(yīng)用程序、設(shè)備、系統(tǒng)等植入管理功能的框架。JMX可以跨越一系列異構(gòu)操作系統(tǒng)平臺(tái)、系統(tǒng)體系結(jié)構(gòu)和網(wǎng)絡(luò)傳輸協(xié)議,靈活的開發(fā)無縫集成的系統(tǒng)、網(wǎng)絡(luò)和服務(wù)管理應(yīng)用。(來源于百度百科)
那我們?cè)趺创蜷_它呢?
簡單,我們打開cmd,輸入jconsole。
然后,選擇我們現(xiàn)在的那個(gè)SpringBoot的項(xiàng)目。
在我們的MBean菜單項(xiàng)中,可以找到org.springframework.boot,Endpoint(端點(diǎn)),里面那些就是我們所對(duì)應(yīng)的端點(diǎn)及其信息了。
我們可以通過點(diǎn)擊Beans端點(diǎn)下的操作,再點(diǎn)擊他的beans按鈕查看我們當(dāng)前所有的bean。
但是這種方式看起來,屬實(shí)不舒服。所以,我們就想,能不能打開web端的這些個(gè)端點(diǎn)信息呢?答案肯定是可以的。
官網(wǎng)給出的打開方式如下:
解釋一下:
- management.endpoints.jmx.exposure.exclude:開啟的 jmx 的端點(diǎn)不包括哪些
- management.endpoints.jmx.exposure.include: 開始 jmx 的哪些端點(diǎn)(默認(rèn)是所有)
- management.endpoints.web.exposure.exclude:開啟的 web 的端點(diǎn)不包括哪些
- management.endpoints.web.exposure.include:開啟web的哪些端點(diǎn)(默認(rèn)是health)
舉兩個(gè)案例:
停止通過 JMX 公開所有端點(diǎn)而僅公開health和info端點(diǎn)
management: endpoints: jmx: exposure: include: "health,info"
通過 HTTP 公開除env和beans端點(diǎn)之外的所有端點(diǎn)
management: endpoints: web: exposure: include: "*" exclude: "env,beans"
我們可以嘗試打開所有的端點(diǎn)看一下:
management: endpoints: web: exposure: include: '*'
編譯一下,然后我們看一下我們的beans端點(diǎn):
里面有我們所有的Bean,包括他們是不是單例,他們的全類名和依賴等等信息。
我們還可以訪問我們的conditions端點(diǎn),查看我們所有的配置(包括我們成功配置的和沒有配置的)
還有他們?yōu)槭裁茨軌蚺渲蒙希?br />
以及他們?yōu)槭裁床荒軌蚺渲蒙希?br />
我們?cè)賮砜匆粋€(gè)常用的端點(diǎn):metrics。
他可以看很多消息,具體翻譯一下即可,比如第一個(gè)http.server.requests,說的就是我們的http請(qǐng)求。我們可以訪問來看一下。
直接在/metrics后邊加上面的字符串就可以了。
1.2 簡單介紹最常用的幾個(gè)端點(diǎn)
1.2.1 health(健康狀況)
健康檢查端點(diǎn),一般用于云平臺(tái),平臺(tái)會(huì)定時(shí)的檢查應(yīng)用的監(jiān)控狀況,為此,我們就需要使用health端點(diǎn)為平臺(tái)返回當(dāng)前應(yīng)用的一系列組件的健康狀況的集合。
重要的幾點(diǎn):
1、健康端點(diǎn)返回的結(jié)果,應(yīng)該是一系列健康檢查后的一個(gè)匯總報(bào)告
2、很多的健康檢查默認(rèn)已經(jīng)自動(dòng)配置好了,比如:數(shù)據(jù)庫、redis等
3、可以很容易的添加自定義的健康檢查機(jī)制
前面我們已經(jīng)說過了端點(diǎn),好像沒啥特別的呀,別急嘛。那主要是因?yàn)槲覀儧]有讓他顯示詳細(xì)的信息。
現(xiàn)在,我們來讓health端點(diǎn)顯示詳細(xì)信息,在配置文件中這么配置:(注意:配置所有的端點(diǎn)的時(shí)候,我們用的是復(fù)數(shù)的endpoints,而配置具體某個(gè)端點(diǎn)的時(shí)候,我們用的是endpoint)
management: endpoint: health: show-details: always
此時(shí)我們?cè)僭L問health端點(diǎn):
解釋一下:
1、首先是db,數(shù)據(jù)庫,健康,通過isValid方法判斷出來。
2、然后是diskSpace,我們的磁盤空間,總計(jì)是240054693888,空閑是148654080000,使用10485760。
3、最后是ping,表示能ping通
1.2.2 metrics(運(yùn)行時(shí)指標(biāo))
指標(biāo)端點(diǎn)主要用于提供詳細(xì)的、層級(jí)的、空間指標(biāo)信息,這些信息可以被pull(主動(dòng)推送)或者push(被動(dòng)獲?。┓绞降玫?。
重要的幾點(diǎn):
1、通過metrics對(duì)接多種監(jiān)控系統(tǒng)
2、簡化核心metrics的開發(fā)
3、添加自定義metrics或者擴(kuò)展已有metrics
這個(gè)我們前面已經(jīng)講過了。他里面含有我們很多的指標(biāo)信息。具體有哪些我們可以進(jìn)入/actuator/metrics下進(jìn)行查看。然后,我們找到我們要查看的指標(biāo)信息對(duì)應(yīng)的字符串,將那段字符串后接到/metrics/后邊即可。
1.2.3 loggers(日志記錄)
這個(gè)感覺也沒啥好說的,自己訪問去看一下即可。
1.3 開啟或關(guān)閉某個(gè)端點(diǎn)
上面講的那種直接開啟web端所有的端點(diǎn)的方式,其實(shí)還是比較危險(xiǎn)的,因此,我們一般需要修改默認(rèn)的配置。讓他不要開啟那么多的端點(diǎn)給我們的http或者JMX。我們修改他的默認(rèn)配置。(默認(rèn)是true,true情況下開啟JMX下所有的端點(diǎn),開啟http下的health端點(diǎn))
management: endpoints: enabled-by-default: false
然后我們想開啟某個(gè)端點(diǎn)的話,我們就在配置文件給他的enable屬性賦予true。
比如,開啟我們的health和info端點(diǎn)
management: endpoint: health: show-details: always enabled: true info: enabled: true
此時(shí),我們?cè)僭L問我們的/actuator可以看到,他只開啟了health和info兩個(gè)端點(diǎn)。
去我們的JMX看一下:(也只剩下兩個(gè)了)
1.4 定制端點(diǎn)
1.4.1 定制我們的Health端點(diǎn)
我們知道這個(gè)端點(diǎn)默認(rèn)的給我們?cè)O(shè)置了數(shù)據(jù)庫和磁盤信息的健康情況。但是,當(dāng)我們引入其他的組件的時(shí)候,我們也希望他判斷一下,這個(gè)組件健不健康,健康的話,給我們返回什么信息,不健康的話,又給我們返回什么信息。
下面,我們就模仿磁盤給出的信息的格式,來給Health端點(diǎn)定制一個(gè)對(duì)我們自己的某個(gè)組件的檢查。
很簡單,只需要寫一個(gè)類繼承AbstractHealthIndicator類或者實(shí)現(xiàn)HealthIndicator接口,然后實(shí)現(xiàn)他的doHealthCheck方法。
我們可以參照DiskSpaceHealthIndicator類的doHealthCheck方法來寫一個(gè)。
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package org.springframework.boot.actuate.system; import java.io.File; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.actuate.health.AbstractHealthIndicator; import org.springframework.boot.actuate.health.Health.Builder; import org.springframework.core.log.LogMessage; import org.springframework.util.unit.DataSize; public class DiskSpaceHealthIndicator extends AbstractHealthIndicator { private static final Log logger = LogFactory.getLog(DiskSpaceHealthIndicator.class); private final File path; private final DataSize threshold; public DiskSpaceHealthIndicator(File path, DataSize threshold) { super("DiskSpace health check failed"); this.path = path; this.threshold = threshold; } protected void doHealthCheck(Builder builder) throws Exception { long diskFreeInBytes = this.path.getUsableSpace(); if (diskFreeInBytes >= this.threshold.toBytes()) { builder.up(); } else { logger.warn(LogMessage.format("Free disk space below threshold. Available: %d bytes (threshold: %s)", diskFreeInBytes, this.threshold)); builder.down(); } builder.withDetail("total", this.path.getTotalSpace()).withDetail("free", diskFreeInBytes).withDetail("threshold", this.threshold.toBytes()).withDetail("exists", this.path.exists()); } }
來,我們繼承并重寫doHealthCheck方法的代碼如下:
package com.example.boot.health; import org.springframework.boot.actuate.health.AbstractHealthIndicator; import org.springframework.boot.actuate.health.Health; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; @Component public class MyIndicator extends AbstractHealthIndicator { @Override protected void doHealthCheck(Health.Builder builder) throws Exception { //判斷的變量 boolean flag = true; //存儲(chǔ)詳細(xì)信息 Map<String, Object> msg = new HashMap<>(); //判斷是否健康 if(flag){ //健康 builder.up(); msg.put("code",200); msg.put("detail","我各個(gè)地方都沒有問題"); }else { //不健康 builder.down(); msg.put("code",500); msg.put("detail","服務(wù)器好像出了什么毛病"); } //將數(shù)據(jù)寫入檢查器 builder.withDetail("codes",100) .withDetails(msg); } }
結(jié)果如下:
1.4.2 定制我們的Info端點(diǎn)
對(duì)于info信息的定制,我們有兩種定制方式。
方式一、在yaml文件中直接配置即可。以info開頭,后邊自己隨便加變量和屬性值。(只有一級(jí)目錄,有二級(jí)目錄會(huì)報(bào)錯(cuò))
info: word: hello,world appName: 我是Info的appName
運(yùn)行:
我們還可以拿pom.xml的東西,通過@@獲取。
info: word: hello,world appName: 我是Info的appName mavenProjectName: @project.name@ mavenAGV: [@project.artifactId@, @project.groupId@, @project.version@]
結(jié)果:
方式二、編寫一個(gè)類實(shí)現(xiàn)InfoContributor接口
package com.example.boot.info; import org.springframework.boot.actuate.info.Info; import org.springframework.boot.actuate.info.InfoContributor; import org.springframework.stereotype.Component; @Component public class MyInfo implements InfoContributor { @Override public void contribute(Info.Builder builder) { builder.withDetail("AppName","Hello,World") .withDetail("msg","我是實(shí)現(xiàn)了InfoContributor的類的消息"); } }
結(jié)果:
1.4.3 定制我們的metrics端點(diǎn)
先打開我們的metrics端點(diǎn)。
management: endpoint: health: show-details: always enabled: true info: enabled: true metrics: enabled: true
然后,假如我們現(xiàn)在要計(jì)算某個(gè)方法被調(diào)用的次數(shù)。
package com.example.boot.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.example.boot.bean.User; import com.example.boot.mapper.UserMapper; import com.example.boot.service.UserService; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { Counter counter; //在構(gòu)造器傳入?yún)?shù)MeterRegistry registry UserServiceImpl(MeterRegistry registry){ //設(shè)置在metrics端點(diǎn)下的名稱 counter = registry.counter("userServiceImpl.list.count"); } @Override public List<User> list() { //次數(shù)加1 counter.increment(); return super.list(); } }
編譯一下,我們可以去看看此時(shí)的metrics端點(diǎn)。
然后訪問幾次我們的localhost:8080/user。
然后看一下我們的metrics/userServiceImpl.list.count。(可以看到我們調(diào)用了10次)
1.4.4 定制我們自己的端點(diǎn)
package com.example.boot.endpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; /** * 使用@Endpoint標(biāo)注我們的端點(diǎn)類,并使用id賦值取名 */ @Endpoint(id = "myEndPoint") @Component public class MyEndPoint { /** * 端點(diǎn)的讀操作 * 返回值無所謂,這里以Map為例返回,比較好看 */ @ReadOperation public Map<String,Object> getDockerInfo(){ Map<String, Object> map = new HashMap<>(); map.put("dockerInfo","docker started......"); return map; } /** * 端點(diǎn)的寫操作 */ @WriteOperation public void stopDocker(){ System.out.println("docker stopped......."); } }
定義完成后,我們可以打開我們的監(jiān)控看一下:發(fā)現(xiàn)他是開著的。
訪問一下:(讀操作)
至于寫操作要怎么執(zhí)行,我們只能打開我們的cmd,進(jìn)我們的JMX看看了。
我們點(diǎn)擊stopDocker。
編譯器后臺(tái)輸出:docker stopped…
1.5 SpringBoot——Admin Server
用來可視化我們所有的監(jiān)控指數(shù)。(包括所有我們開啟的端點(diǎn)的信息)具體可以點(diǎn)擊這個(gè)鏈接觀看尚硅谷的視頻(時(shí)長13分25秒,每一秒都干貨滿滿)。
運(yùn)行的圖大致如下:(部分截圖僅供參考)
圖1:
圖2:
圖3:
到此這篇關(guān)于SpringBoot指標(biāo)監(jiān)控的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)SpringBoot指標(biāo)監(jiān)控內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Cloud 動(dòng)態(tài)刷新配置信息教程詳解
這篇文章主要介紹了Spring Cloud 動(dòng)態(tài)刷新配置信息的教程,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-06-06SpringBoot后端接口的實(shí)現(xiàn)(看這一篇就夠了)
這篇文章主要介紹了SpringBoot后端接口的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09改善Java代碼之慎用java動(dòng)態(tài)編譯
這篇文章主要介紹了改善Java代碼之慎用java動(dòng)態(tài)編譯,需要的朋友可以參考下2021-04-04Java實(shí)現(xiàn)XML格式與JSON格式互相轉(zhuǎn)換的方法
這篇文章主要介紹了Java實(shí)現(xiàn)XML格式與JSON格式互相轉(zhuǎn)換的方法,方法通過實(shí)例代碼給大家介紹的非常詳細(xì),選擇使用哪種格式通常取決于項(xiàng)目的需求和上下文,所以格式轉(zhuǎn)換就成了我們必備的技能,具體實(shí)現(xiàn)代碼跟隨小編一起看看吧2023-10-10springboot通過SchedulingConfigurer實(shí)現(xiàn)多定時(shí)任務(wù)注冊(cè)及動(dòng)態(tài)修改執(zhí)行周期(示例詳解)
這篇文章主要介紹了springboot通過SchedulingConfigurer實(shí)現(xiàn)多定時(shí)任務(wù)注冊(cè)及動(dòng)態(tài)修改執(zhí)行周期,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06