天天看點

面試官:聊一聊SpringBoot服務監控機制前言SpringBoot 監控其他監控總結

面試官:聊一聊SpringBoot服務監控機制

  • 前言
  • SpringBoot 監控
    • HTTP Endpoints 監控
      • 内置端點
        • health 端點
        • loggers 端點
        • metrics 端點
      • 自定義監控端點
        • 自定義監控端點常用注解
        • 來,一起寫一個自己的監控端點
    • JMX 監控
      • 如何手動注冊一個 JMX MBean
  • 其他監控
  • 總結

前言

任何一個服務如果沒有監控,那就是兩眼一抹黑,無法知道目前服務的運作情況,也就無法對可能出現的異常狀況進行很好的處理,是以對任意一個服務來說,監控都是必不可少的。

就目前而言,大部分微服務應用都是基于

SpringBoot

來建構,是以了解

SpringBoot

的監控特性是非常有必要的,而

SpringBoot

也提供了一些特性來幫助我們監控應用。

本文基于

SpringBoot 2.3.1.RELEASE

版本示範。

SpringBoot 監控

SpringBoot

中的監控可以分為

HTTP

端點和

JMX

兩種方式來監控目前應用的運作狀況和名額收集

HTTP Endpoints 監控

執行器端點允許您監視應用程式并與之互動。

SpringBoot

包括許多内置的端點,并允許我們添加自己的端點。可以通過

HTTP

JMX

啟用或禁用每個端點,并公開(使其可以遠端通路)。每個端點都有一個唯一的

id

,通路時可以通過如下位址進行通路:

http:ip:port/{id}

(SpringBoot 1.x ),而在

SpringBoot 2.x

版本中,預設新增了一個

/actuator

作為基本路,通路位址則對應為 :

http:ip:port/actuator/{id}

使用

HTTP

監控非常簡單,在

SpringBoot

項目中,引入如下依賴:

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

預設就可以通過位址

http:localhost:8080/actuator/health

,通路之後得到如下結果:

面試官:聊一聊SpringBoot服務監控機制前言SpringBoot 監控其他監控總結

SpringBoot

中提供了非常多的預設端點監控,但是出于安全考慮,預設情況下有些端點并不是開啟狀态,如

shutdown

端點就是預設關閉的。

内置端點

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

端點,是以如果需要允許端點對外暴露,可以通過如下配置(如果想要暴露所有的端點,則可以直接配置

"*"

):

management:
  endpoints:
    web:
      exposure:
        include: [health,info,mappings] //或者直接配置 "*"
           

另外,開啟或禁用某一個端點,也可以通過通過如下配置進行動态控制:

management.endpoint.<id>.enabled=true
           

接下來我們挑選幾個重點的端點來介紹一下。

health 端點

health

斷點預設隻是展示目前應用健康資訊,但是我們可以通過另一個配置打開詳細資訊,這樣不僅僅會監控目前應用,還會監控與目前應用相關的其他第三方應用,如

Redis

management:
  endpoint:
    health:
      show-details: always
           

這個配置打開之後,我們連接配接上

Redis

之後再次通路

health

端點,就可以展示

Redis

服務的健康資訊了:

面試官:聊一聊SpringBoot服務監控機制前言SpringBoot 監控其他監控總結

loggers 端點

通路

http://localhost:8080/actuator/loggers

可以檢視目前應用的日志級别等資訊:

面試官:聊一聊SpringBoot服務監控機制前言SpringBoot 監控其他監控總結

這裡面本身并不特别,但是有一個功能卻非常有用,比如我們生産環境日志級别一般都是

info

,但是現在有一個

bug

通過

info

級别無法排查,那麼我們就可以臨時修改

log

級别。

比如上圖中的

ROOT

節點是

info

級别,那麼我們可以通過

postman

等工具來發一個

post

請求修改日志級别。

面試官:聊一聊SpringBoot服務監控機制前言SpringBoot 監控其他監控總結

修改之後就會發現,日志由原來的

info

變成了

debug

面試官:聊一聊SpringBoot服務監控機制前言SpringBoot 監控其他監控總結

metrics 端點

metrics

是一個非常重要的監控端點,其監控内容覆寫了

JVM

記憶體、堆、類加載、處理器和

tomcat

容器等一些重要名額:

面試官:聊一聊SpringBoot服務監控機制前言SpringBoot 監控其他監控總結

可以看到這裡面包含了非常多的名額,任意通路一個名額就可以檢視對應的名額資訊:

面試官:聊一聊SpringBoot服務監控機制前言SpringBoot 監控其他監控總結

自定義監控端點

通過上面的介紹,可以看到

SpringBoot

提供的監控非常強大,但是就算再全面的監控也不可能滿足所有人的需求,是以

SpringBoot

也支援自定義監控端點。

自定義監控端點常用注解

自定義一個監控端點主要有如下常用注解:

  • @Endpoint:定義一個監控端點,同時支援

    HTTP

    JMX

    兩種方式。
  • @WebEndpoint:定義一個監控端點,隻支援

    HTTP

    方式。
  • @JmxEndpoint:定義一個監控端點,隻支援

    JMX

    方式。

以上三個注解作用在類上,表示目前類是一個監控端點,另外還有一些注解會用在方法和參數上:

  • @ReadOperation:作用在方法上,可用來傳回端點展示的資訊(通過

    Get

    方法請求)。
  • @WriteOperation:作用在方法上,可用來修改端點展示的資訊(通過

    Post

    方法請求)。
  • @DeleteOperation:作用在方法上,可用來删除對應端點資訊(通過

    Delete

    方法請求)。
  • @Selector:作用在參數上,用來定位一個端點的具體名額路由。

來,一起寫一個自己的監控端點

  • 定義一個類,并使用

    @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;
            }
        }
    }
}
           
  1. @Component

    注解表示将該類交給

    Spring

    進行管理,或者也可以再定義一個

    Configuration

    類來加載該

    Bean

    也可以,當然,如果我們需要提供給第三方使用,如果無法保證目前包名被掃描,則需要使用

    SpringBoot

    的自動裝配機制将該類進行管理。
  2. @ReadOperation

    方法可以傳回

    String

    或者

    JSONObject

    或者

    Map

    集合等。
  3. 參數上加了

    @Selector

    注解則表示通路斷端點的時候可以直接通路子節點。

完成了上面的類,啟動

SpringBoot

應用,接下來就可以直接通過

http://localhost:8080/actuator/myEndpoint

進行通路了:

面試官:聊一聊SpringBoot服務監控機制前言SpringBoot 監控其他監控總結

同時,因為

test3_1

方法使用了

@Selector

注解,是以我們可以通過這個方法每一個名額的明細:

面試官:聊一聊SpringBoot服務監控機制前言SpringBoot 監控其他監控總結

而帶有

@WriteOperation

注解的方法可以用來修改名額,這個方法需要用

post

進行通路,通路的參數可以直接使用字元串傳參,也可以直接使用

json

進行傳參,修改之後再次檢視就可以發現名額已經被動态修改:

面試官:聊一聊SpringBoot服務監控機制前言SpringBoot 監控其他監控總結

JMX 監控

JMX

全稱為 Java Management Extensions,即

Java

管理擴充。它提供了對

Java

應用程式和

JVM

的監控管理。通過

JMX

我們可以監控伺服器中各種資源的使用情況以及線程,記憶體和

CPU

等使用情況。

打開

jdk

下提供的工具

jConsole

面試官:聊一聊SpringBoot服務監控機制前言SpringBoot 監控其他監控總結

打開之後這裡會監控到我們已經啟動的應用,輕按兩下進入:

面試官:聊一聊SpringBoot服務監控機制前言SpringBoot 監控其他監控總結

如何手動注冊一個 JMX MBean

  • 定義一個接口

    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

面試官:聊一聊SpringBoot服務監控機制前言SpringBoot 監控其他監控總結

同樣的,

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

的方法。