任何一個服務若是沒有監控,那就是兩眼一抹黑,沒法知道當前服務的運行狀況,也就沒法對可能出現的異常情況進行很好的處理,因此對任意一個服務來講,監控都是必不可少的。java
就目前而言,大部分微服務應用都是基於 SpringBoot
來構建,因此瞭解 SpringBoot
的監控特性是很是有必要的,而 SpringBoot
也提供了一些特性來幫助咱們監控應用。web
本文基於 SpringBoot 2.3.1.RELEASE
版本演示。spring
SpringBoot
中的監控能夠分爲 HTTP
端點和 JMX
兩種方式來監控當前應用的運行情況和指標收集json
執行器端點容許您監視應用程序並與之交互。SpringBoot
包括許多內置的端點,並容許咱們添加本身的端點。能夠經過 HTTP
或 JMX
啓用或禁用每一個端點,並公開(使其能夠遠程訪問)。每一個端點都有一個惟一的 id
,訪問時能夠經過以下地址進行訪問:http:ip:port/{id}
(SpringBoot 1.x ),而在 SpringBoot 2.x
版本中,默認新增了一個 /actuator
做爲基本路,訪問地址則對應爲 :http:ip:port/actuator/{id}
。緩存
使用 HTTP
監控很是簡單,在 SpringBoot
項目中,引入以下依賴:tomcat
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies>
默認就能夠經過地址 http:localhost:8080/actuator/health
,訪問以後獲得以下結果:安全
SpringBoot
中提供了很是多的默認端點監控,可是出於安全考慮,默認狀況下有些端點並非開啓狀態,如 shutdown
端點就是默認關閉的。springboot
SpringBoot
中默認提供的經常使用內置端點以下:服務器
端點 id | 描述 |
---|---|
auditevents | 公開當前應用程序的審計事件信息,須要 AuditEventRepository Bean。 |
beans | 展現程序中全部的 Bean。 |
caches | 公開可用的緩存。 |
conditions | 展現配置類或者自動裝配類中的條件,以及它們匹配或者不匹配的緣由。 |
configprops | 顯示全部 @ConfigurationProperties 中的配置屬性。 |
env | 顯示 ConfigurableEnvironment 中的全部環境。 |
health | 顯示應用程序運行情況信息。 |
httptrace | 顯示 HTTP 跟蹤信息(默認狀況下統計最近 100 次請求),須要 HttpTraceRepository Bean。 |
info | 顯示任意程序信息。 |
integrationgraph | 顯示 Spring 集成圖,須要依賴 spring-integration-core。 |
loggers | 展現和修改應用中的 loggers 配置。 |
metrics | 展現當前應用監控指標的度量。 |
mappings | 展現全部 @RequestMapping 路徑。 |
scheduledtasks | 展現應用中的全部定時任務信息。 |
sessions | 容許從 Spring 會話支持的會話存儲中檢索和刪除用戶會話。須要使用基於 Spring Session web應用程序。 |
shutdown | 優雅的關閉程序,默認禁止了該端點的訪問。 |
雖說這裏的大部分端點都是默認開啓的,可是默認暴露(容許對外訪問)的只有 health
和 info
端點,因此若是須要容許端點對外暴露,能夠經過以下配置(若是想要暴露全部的端點,則能夠直接配置 "*"
):session
management: endpoints: web: exposure: include: [health,info,mappings] //或者直接配置 "*"
另外,開啓或禁用某一個端點,也能夠經過經過以下配置進行動態控制:
management.endpoint.<id>.enabled=true
接下來咱們挑選幾個重點的端點來介紹一下。
health
斷點默認只是展現當前應用健康信息,可是咱們能夠經過另外一個配置打開詳細信息,這樣不只僅會監控當前應用,還會監控與當前應用相關的其餘第三方應用,如 Redis
。
management: endpoint: health: show-details: always
這個配置打開以後,咱們鏈接上 Redis
以後再次訪問 health
端點,就能夠展現 Redis
服務的健康信息了:
訪問 http://localhost:8080/actuator/loggers
能夠查看當前應用的日誌級別等信息:
這裏面自己並不特別,可是有一個功能卻很是有用,好比咱們生產環境日誌級別通常都是 info
,可是如今有一個 bug
經過 info
級別沒法排查,那麼咱們就能夠臨時修改 log
級別。
好比上圖中的 ROOT
節點是 info
級別,那麼咱們能夠經過 postman
等工具來發一個 post
請求修改日誌級別。
修改以後就會發現,日誌由原來的 info
變成了 debug
:
metrics
是一個很是重要的監控端點,其監控內容覆蓋了 JVM
內存、堆、類加載、處理器和 tomcat
容器等一些重要指標:
能夠看到這裏麪包含了很是多的指標,任意訪問一個指標就能夠查看對應的指標信息:
經過上面的介紹,能夠看到 SpringBoot
提供的監控很是強大,可是就算再全面的監控也不可能知足全部人的需求,因此 SpringBoot
也支持自定義監控端點。
自定義一個監控端點主要有以下經常使用註解:
HTTP
和 JMX
兩種方式。HTTP
方式。JMX
方式。以上三個註解做用在類上,表示當前類是一個監控端點,另外還有一些註解會用在方法和參數上:
Get
方法請求)。Post
方法請求)。Delete
方法請求)。@Endpoint
註解標註標識,同時定義幾個方法用 @ReadOperation
和 @WriteOperation
註解來標註:@Endpoint(id="myEndpoint") @Component public class MyEndpoint { private String STATUS = "up"; private String DETAIL = "一切正常"; // @ReadOperation // public String test1(){ // return "wolf"; // } // @ReadOperation // public Map<String,String> test2(){ // Map<String,String> map = new HashMap(); // map.put("status","up"); // return map; // } @ReadOperation public JSONObject test3(){ JSONObject jsonObject= new JSONObject(); jsonObject.put("status",STATUS); jsonObject.put("detail",DETAIL); return jsonObject; } @ReadOperation public JSONObject test3_1(@Selector String name){ JSONObject jsonObject= new JSONObject(); if ("status".equals(name)){ jsonObject.put("status",STATUS); }else if ("detail".equals(name)){ jsonObject.put("detail",DETAIL); } return jsonObject; } @WriteOperation//動態修改指標 public void test4(@Selector String name,@Nullable String value){ if (!StringUtils.isEmpty(value)){ if ("status".equals(name)){ STATUS = value; }else if ("detail".equals(name)){ DETAIL = value; } } } }
@Component
註解表示將該類交給 Spring
進行管理,或者也能夠再定義一個 Configuration
類來加載該 Bean
也能夠,固然,若是咱們須要提供給第三方使用,若是沒法保證當前包名被掃描,則須要使用 SpringBoot
的自動裝配機制將該類進行管理。@ReadOperation
方法能夠返回 String
或者 JSONObject
或者 Map
集合等。@Selector
註解則表示訪問斷端點的時候能夠直接訪問子節點。完成了上面的類,啓動 SpringBoot
應用,接下來就能夠直接經過 http://localhost:8080/actuator/myEndpoint
進行訪問了:
同時,由於 test3_1
方法使用了 @Selector
註解,因此咱們能夠經過這個方法每個指標的明細:
而帶有 @WriteOperation
註解的方法能夠用來修改指標,這個方法須要用 post
進行訪問,訪問的參數能夠直接使用字符串傳參,也能夠直接使用 json
進行傳參,修改以後再次查看就能夠發現指標已經被動態修改:
JMX
全稱爲 Java Management Extensions,即 Java
管理擴展。它提供了對 Java
應用程序和 JVM
的監控管理。經過JMX
咱們能夠監控服務器中各類資源的使用狀況以及線程,內存和 CPU
等使用狀況。
打開 jdk
下提供的工具 jConsole
:
打開以後這裏會監控到咱們已經啓動的應用,雙擊進入:
SystemInfoMBean
(注意名字必需要用 MBean
結尾):public interface SystemInfoMBean { int getCpuCore(); long getTotalMemory(); void shutdown(); }
SystemInfoMBean
接口,實現類的明明方式爲接口名去掉 MBean
:public class SystemInfo implements SystemInfoMBean { @Override public int getCpuCore() { return Runtime.getRuntime().availableProcessors(); } @Override public long getTotalMemory() { return Runtime.getRuntime().totalMemory(); } @Override public void shutdown() { System.exit(0); } }
public class JmxRegisterMain { public static void main(String[] args) throws NotCompliantMBeanException, InstanceAlreadyExistsException, MBeanRegistrationException, MalformedObjectNameException, IOException { MBeanServer mBeanServer= ManagementFactory.getPlatformMBeanServer(); ObjectName objectName=new ObjectName("com.lonely.wolf.note.springboot.actuator.jmx:type=SystemInfo"); SystemInfo SystemInfo =new SystemInfo(); mBeanServer.registerMBean(SystemInfo,objectName);//註冊 System.in.read();//防止程序結束 } }
運行該 main
方法,再打開 jConsole
就能夠看到成功註冊了一個 MBean
:
一樣的,Spring
當中只要咱們使用了 @@Endpoint
或者 @JmxEndpoint
註解,就會自動幫咱們註冊一個 MBean
,其原理也是利用了自動裝配機制。
除了 SpringBoot
自帶的監控以外,也有其餘第三方開源的強大監控系統,如 Prometheus
,並且 SpringBoot
也將其進行了集成,使用 Prometheus
時只須要引入以下 jar
包便可:
<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency>
固然,若是使用 Prometheus
的話須要單獨安裝,並且通常會選擇 Prometheus
+ Grafana
來共同實現一個監控平臺,在這裏就不作過多介紹,若是感興趣的朋友能夠本身去了解下這兩種軟件的使用。
本文主要講述了 Spring Boot actuator
的使用,並分別介紹了其中兩種監控類型 HTTP
和 JMX
,最後經過一個例子來實現了自定義的端點,同時也實現了手動註冊一個 MBean
的方法。