<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試官:SpringBoot 服務(wù)監(jiān)控怎么做?線程,JVM堆信息怎么收集?

          共 15282字,需瀏覽 31分鐘

           ·

          2021-09-12 11:53

          你知道的越多,不知道的就越多,業(yè)余的像一棵小草!

          你來,我們一起精進(jìn)!你不來,我和你的競爭對手一起精進(jìn)!

          編輯:業(yè)余草

          推薦:https://www.xttblog.com/?p=5279

          今年面試了非常多的程序員,不少人簡歷中寫著會 SpringCloud、SpringBoot。于是我問,你們的服務(wù)監(jiān)控是用什么做的?不少人就當(dāng)場露餡了,我自己都感覺很不好意思繼續(xù)追問,感覺圓場。

          這里我摘錄幾個回答,大家看看:監(jiān)控功能還沒做;監(jiān)控功能是其他人寫的,我不太清楚;監(jiān)控是運(yùn)維的工作,運(yùn)維團(tuán)隊(duì)維護(hù)的,具體我不清楚。。。

          這就是很多人做微服務(wù),或者學(xué)微服務(wù),以及進(jìn)行微服務(wù)的架構(gòu)轉(zhuǎn)型所忽略的,服務(wù)監(jiān)控這塊沒有跟上。

          剛好這兩天群里也有人在討論這個問題,因此今天我們一起來討論一下,微服務(wù)的監(jiān)控如何做?由于大部分企業(yè)的微服務(wù)應(yīng)用都是 SpringBoot 應(yīng)用,因此我這里自然而然的想到了借助 Spring Boot 的 Actuator 模塊。(沒吃過豬肉總聽過豬叫見過豬跑吧??)。

          這篇文章是我在完成公司架構(gòu)變更之后,對 SpringBoot Actuator 模塊學(xué)習(xí)應(yīng)用的總結(jié)。在本篇文章中,你可以學(xué)習(xí)到:

          「1、」 Spring Boot Actuator 的快速使用入門
          「2、」 Spring Boot Actuator 的一些重要的 endpoints 的介紹
          「3、」 如何通過 Actuator 模塊實(shí)時(shí)查看當(dāng)前應(yīng)用的線程 dump 信息
          「4、」 如何通過 Actuator 模塊實(shí)時(shí)查看當(dāng)前應(yīng)用的堆信息
          「5、」 如何通過 Actuator 模塊實(shí)時(shí)修改當(dāng)前應(yīng)用的日志打印等級
          「6、」 ...

          后面找機(jī)會我還會介紹:

          TODO:SpringBoot 微服務(wù)應(yīng)用集成 Prometheus + Grafana 實(shí)現(xiàn)監(jiān)控告警

          什么是 Spring Boot Actuator

          Spring Boot Actuator 模塊提供了生產(chǎn)級別的功能,比如健康檢查,審計(jì),指標(biāo)收集,HTTP 跟蹤等,幫助我們監(jiān)控和管理 Spring Boot 應(yīng)用。這個模塊是一個采集應(yīng)用內(nèi)部信息暴露給外部的模塊,上述的功能都可以通過HTTP 和 JMX 訪問。

          因?yàn)楸┞秲?nèi)部信息的特性,Actuator 也可以和一些外部的應(yīng)用監(jiān)控系統(tǒng)整合(Prometheus, Graphite,DataDog,Influx,Wavefront,New Relic等)。這些監(jiān)控系統(tǒng)提供了出色的儀表板,圖形,分析和警報(bào),可幫助你通過一個統(tǒng)一友好的界面,監(jiān)視和管理你的應(yīng)用程序。

          Actuator 使用 Micrometer 與這些外部應(yīng)用程序監(jiān)視系統(tǒng)集成。這樣一來,只需很少的配置即可輕松集成外部的監(jiān)控系統(tǒng)。

          ?

          Micrometer 為 Java 平臺上的性能數(shù)據(jù)收集提供了一個通用的 API,應(yīng)用程序只需要使用 Micrometer 的通用 API 來收集性能指標(biāo)即可。Micrometer 會負(fù)責(zé)完成與不同監(jiān)控系統(tǒng)的適配工作。這就使得切換監(jiān)控系統(tǒng)變得很容易。

          對比 Slf4j 之于 Java Logger 中的定位。

          ?

          快速開始,創(chuàng)建一個Spring Boot Actuator Demo

          我們先創(chuàng)建一個 demo 應(yīng)用。

          「你可以通過 Spring Boot CLI 創(chuàng)建:」

          spring init -d=web,actuator -n=actuator-demo actuator-demo

          「或者通過 Spring Initializr 創(chuàng)建:」

          Spring Initializr

          「對應(yīng)的 maven 依賴:」

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

          「對應(yīng)的 Gradle 依賴:」

          dependencies {  
              compile("org.springframework.boot:spring-boot-starter-actuator")
          }

          Endpoints 介紹

          Spring Boot 提供了所謂的 endpoints (下文翻譯為端點(diǎn))給外部來與應(yīng)用程序進(jìn)行訪問和交互。

          打比方來說,/health 端點(diǎn) 提供了關(guān)于應(yīng)用健康情況的一些基礎(chǔ)信息。metrics 端點(diǎn)提供了一些有用的應(yīng)用程序指標(biāo)(JVM 內(nèi)存使用、系統(tǒng) CPU 使用等)。

          這些 Actuator 模塊本來就有的端點(diǎn)我們稱之為原生端點(diǎn)。根據(jù)端點(diǎn)的作用的話,我們大概可以分為三大類:

          應(yīng)用配置類: 獲取應(yīng)用程序中加載的應(yīng)用配置、環(huán)境變量、自動化配置報(bào)告等與 Spring Boot 應(yīng)用密切相關(guān)的配置類信息。

          度量指標(biāo)類:獲取應(yīng)用程序運(yùn)行過程中用于監(jiān)控的度量指標(biāo),比如:內(nèi)存信息、線程池信息、HTTP 請求統(tǒng)計(jì)等。

          操作控制類:提供了對應(yīng)用的關(guān)閉等操作類功能。

          ?

          詳細(xì)的原生端點(diǎn)介紹,請以官網(wǎng)為準(zhǔn),這里就不贅述徒增篇幅。

          ?

          需要注意的就是:

          1、每一個端點(diǎn)都可以通過配置來單獨(dú)禁用或者啟動

          2、不同于 Actuator 1.x,「Actuator 2.x 的大多數(shù)端點(diǎn)默認(rèn)被禁掉」。Actuator 2.x 中的默認(rèn)端點(diǎn)增加了/actuator前綴。默認(rèn)暴露的兩個端點(diǎn)為/actuator/health和 /actuator/info

          端點(diǎn)暴露配置

          我們可以通過以下配置,來配置通過 JMX 和 HTTP 暴露的端點(diǎn)。

          端點(diǎn)暴露配置

          可以打開所有的監(jiān)控點(diǎn)。

          management.endpoints.web.exposure.include=\*

          也可以選擇打開部分,"*" 代表暴露所有的端點(diǎn),如果指定多個端點(diǎn),用","分開。

          management.endpoints.web.exposure.exclude=beans,trace

          Actuator 默認(rèn)所有的監(jiān)控點(diǎn)路徑都在/actuator/*,當(dāng)然如果有需要這個路徑也支持定制。

          management.endpoints.web.base-path=/minitor

          設(shè)置完重啟后,再次訪問地址就會變成/minitor/*

          「現(xiàn)在我們按照如下配置:」

          # "\*" 代表暴露所有的端點(diǎn) 如果指定多個端點(diǎn),用","分開  
          management.endpoints.web.exposure.include=\*
          # 賦值規(guī)則同上
          management.endpoints.web.exposure.exclude=

          啟動 demo 程序,訪問http://localhost:8080/actuator,查看暴露出來的端點(diǎn):

          actuator監(jiān)控
          ?

          上面這樣顯示是因?yàn)?chrome 瀏覽器安裝了 JSON-handle 插件,實(shí)際上就是返回一大段 json。

          ?

          下面,我會著重介紹幾個比較重要的端點(diǎn)。

          重要端點(diǎn)解析

          /health端點(diǎn)

          /health端點(diǎn)會聚合你程序的健康指標(biāo),來檢查程序的健康情況。端點(diǎn)公開的應(yīng)用健康信息取決于:

          management.endpoint.health.show-details=always

          該屬性可以使用以下值之一進(jìn)行配置:

          端點(diǎn)解析

          按照上述配置,配置成always之后,我們啟動項(xiàng)目,訪問http://localhost:8080/actuator/health端口,可以看到這樣的信息:

          health端口

          是不是感覺好像健康信息有點(diǎn)少?先別急,那是因?yàn)槲覀儎?chuàng)建的是一個最基礎(chǔ)的 Demo 項(xiàng)目,沒有依賴很多的組件。

          /health端點(diǎn)有很多自動配置的健康指示器:如 redis、rabbitmq、db 等組件。當(dāng)你的項(xiàng)目有依賴對應(yīng)組件的時(shí)候,這些健康指示器就會被自動裝配,繼而采集對應(yīng)的信息。如上面的 diskSpace 節(jié)點(diǎn)信息就是DiskSpaceHealthIndicator在起作用。

          DiskSpaceHealthIndicator
          ?

          上述截圖取自官方文檔

          ?

          這是我另一個項(xiàng)目的/health端點(diǎn)信息。

          /health端點(diǎn)信息

          當(dāng)如上的組件有一個狀態(tài)異常,應(yīng)用服務(wù)的整體狀態(tài)即為 down。我們也可以通過配置禁用某個組件的健康監(jiān)測。

          management.health.mongo.enabled: false

          「或者禁用所有自動配置的健康指示器:」

          management.health.defaults.enabled: false

          自定義 Health Indicator

          當(dāng)然你也可以自定義一個Health Indicator,只需要實(shí)現(xiàn)HealthIndicator 接口或者繼承AbstractHealthIndicator類。

          @Component  
          public class CustomHealthIndicator extends AbstractHealthIndicator {
              @Override  
              protected void doHealthCheck(Health.Builder builder) throws Exception {  
                  // 使用 builder 來創(chuàng)建健康狀態(tài)信息  
                  // 如果你throw 了一個 exception,那么status 就會被置為DOWN,異常信息會被記錄下來  
                  builder.up()  
                          .withDetail("app""這個項(xiàng)目很健康")  
                          .withDetail("error""Nothing, I'm very good");  
              }  
          }

          「最終效果:」

          自定義 Health Indicator

          5.2 /metrics端點(diǎn)

          /metrics端點(diǎn)用來返回當(dāng)前應(yīng)用的各類重要度量指標(biāo),比如:內(nèi)存信息、線程信息、垃圾回收信息、tomcat、數(shù)據(jù)庫連接池等。

          {  
              "names": [
                  "tomcat.threads.busy",
                  "jvm.threads.states",
                  "jdbc.connections.active",
                  "jvm.gc.memory.promoted",
                  "http.server.requests",
                  "hikaricp.connections.max",
                  "hikaricp.connections.min",
                  "jvm.memory.used",
                  "jvm.gc.max.data.size",
                  "jdbc.connections.max",
                   ....
              ]
          }

          不同于 1.x,Actuator 在這個界面看不到具體的指標(biāo)信息,只是展示了一個指標(biāo)列表。為了獲取到某個指標(biāo)的詳細(xì)信息,我們可以請求具體的指標(biāo)信息,像這樣:

          http://localhost:8080/actuator/metrics/{MetricName}

          比如我訪問/actuator/metrics/jvm.memory.max,返回信息如下:

          jvm.memory.max

          你也可以用 query param 的方式查看單獨(dú)的一塊區(qū)域。比如你可以訪問/actuator/metrics/jvm.memory.max?tag=id:Metaspace。結(jié)果就是:

          Metaspace

          /loggers端點(diǎn)

          /loggers 端點(diǎn)暴露了我們程序內(nèi)部配置的所有 logger 的信息。我們訪問/actuator/loggers可以看到

          loggers端點(diǎn)

          你也可以通過下述方式訪問單獨(dú)一個 logger。

          http://localhost:8080/actuator/loggers/{name}

          比如我現(xiàn)在訪問 root logger,http://localhost:8080/actuator/loggers/root

          {  
              "configuredLevel""INFO",  
              "effectiveLevel""INFO"  
          }

          改變運(yùn)行時(shí)的日志等級

          /loggers端點(diǎn)我最想提的就是這個功能,能夠動態(tài)修改你的日志等級。

          比如,我們可以通過下述方式來修改 root,logger 的日志等級。我們只需要發(fā)起一個 URL 為http://localhost:8080/actuator/loggers/rootPOST請求,POST 報(bào)文如下:

          {  
             "configuredLevel": "DEBUG"
          }
          POST請求

          仔細(xì)想想,這個功能是不是非常有用。「如果在生產(chǎn)環(huán)境中,你想要你的應(yīng)用輸出一些 Debug 信息以便于你診斷一些異常情況,你你只需要按照上述方式就可以修改,而不需要重啟應(yīng)用。」

          ?

          如果想重置成默認(rèn)值,把 value 改成 null

          ?

          /info端點(diǎn)

          /info端點(diǎn)可以用來展示你程序的信息。我理解過來就是一些程序的基礎(chǔ)信息。并且你可以按照自己的需求在配置文件application.properties中個性化配置(默認(rèn)情況下,該端點(diǎn)只會返回一個空的 json 內(nèi)容。):

          info.app.name=actuator-test-demo  
          info.app.encoding=UTF-8
          info.app.java.source=1.8
          info.app.java.target=1.8
          # 在 maven 項(xiàng)目中你可以直接用下列方式引用 maven properties的值
          [email protected]@
          [email protected]@
          [email protected]@

          啟動項(xiàng)目,訪問http://localhost:8080/actuator/info

          {  
              "app": {  
                  "encoding""UTF-8",  
                  "java": {  
                      "source""1.8.0_131",  
                      "target""1.8.0_131"  
                  },  
                  "name""actuator-test-demo"  
              }  
          }

          /beans端點(diǎn)

          /beans端點(diǎn)會返回 Spring 容器中所有 bean 的別名、類型、是否單例、依賴等信息。

          訪問http://localhost:8080/actuator/beans,返回如下:

          beans端點(diǎn)

          /heapdump 端點(diǎn)

          訪問:http://localhost:8080/actuator/heapdump會自動生成一個 Jvm 的堆文件  heapdump。我們可以使用 JDK 自帶的 Jvm 監(jiān)控工具 VisualVM 打開此文件查看內(nèi)存快照。

          VisualVM查看內(nèi)存快照

          /threaddump 端點(diǎn)

          這個端點(diǎn)我個人覺得特別有用,方便我們在日常定位問題的時(shí)候查看線程的情況。主要展示了線程名、線程 ID、線程的狀態(tài)、是否等待鎖資源、線程堆棧等信息。就是可能查看起來不太直觀。訪問http://localhost:8080/actuator/threaddump返回如下:

          threaddump 端點(diǎn)

          /shutdown端點(diǎn)

          這個端點(diǎn)屬于操作控制類端點(diǎn),可以優(yōu)雅關(guān)閉 Spring Boot 應(yīng)用。要使用這個功能首先需要在配置文件中開啟:

          management.endpoint.shutdown.enabled=true

          由于 「shutdown 接口默認(rèn)只支持 POST 請求」,我們啟動Demo項(xiàng)目,向http://localhost:8080/actuator/shutdown發(fā)起POST請求。返回信息:

          {  
              "message": "Shutting down, bye..."
          }

          然后應(yīng)用程序被關(guān)閉。

          由于開放關(guān)閉應(yīng)用的操作本身是一件「非常危險(xiǎn)」的事,所以真正在線上使用的時(shí)候,我們需要對其加入一定的保護(hù)機(jī)制,比如:「定制 Actuator 的端點(diǎn)路徑、整合 Spring Security 進(jìn)行安全校驗(yàn)」等。(不是特別必要的話,這個端點(diǎn)不用開)

          整合 Spring Security 對端點(diǎn)進(jìn)行安全校驗(yàn)

          由于端點(diǎn)的信息和產(chǎn)生的交互都是非常敏感的,必須防止未經(jīng)授權(quán)的外部訪問。如果您的應(yīng)用程序中存在「Spring Security」的依賴,則默認(rèn)情況下使用「基于表單的 HTTP 身份驗(yàn)證」來保護(hù)端點(diǎn)。

          如果沒有,只需要增加對應(yīng)的依賴即可:

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

          添加之后,我們需要定義安全校驗(yàn)規(guī)則,來覆蓋 Spring Security 的默認(rèn)配置。

          這里我給出了兩個版本的模板配置:

          import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;  
          import org.springframework.boot.actuate.context.ShutdownEndpoint;  
          import org.springframework.boot.autoconfigure.security.servlet.PathRequest;  
          import org.springframework.context.annotation.Configuration;  
          import org.springframework.security.config.annotation.web.builders.HttpSecurity;  
          import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

          @Configuration  
          public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {

              /\*  
               \* version1:  
               \* 1. 限制 '/shutdown'端點(diǎn)的訪問,只允許ACTUATOR\_ADMIN訪問  
               \* 2. 允許外部訪問其他的端點(diǎn)  
               \* 3. 允許外部訪問靜態(tài)資源  
               \* 4. 允許外部訪問 '/'  
               \* 5. 其他的訪問需要被校驗(yàn)  
               \* version2:  
               \* 1. 限制所有端點(diǎn)的訪問,只允許ACTUATOR\_ADMIN訪問  
               \* 2. 允許外部訪問靜態(tài)資源  
               \* 3. 允許外部訪問 '/'  
               \* 4. 其他的訪問需要被校驗(yàn)  
               \*/

              @Override  
              protected void configure(HttpSecurity http) throws Exception {  
                  // version1  
          //        http  
          //                .authorizeRequests()  
          //                    .requestMatchers(EndpointRequest.to(ShutdownEndpoint.class))  
          //                        .hasRole("ACTUATOR\_ADMIN")  
          //                .requestMatchers(EndpointRequest.toAnyEndpoint())  
          //                    .permitAll()  
          //                .requestMatchers(PathRequest.toStaticResources().atCommonLocations())  
          //                    .permitAll()  
          //                .antMatchers("/")  
          //                    .permitAll()  
          //                .antMatchers("/\*\*")  
          //                    .authenticated()  
          //                .and()  
          //                .httpBasic();

                  // version2  
                  http  
                          .authorizeRequests()  
                          .requestMatchers(EndpointRequest.toAnyEndpoint())  
                              .hasRole("ACTUATOR\_ADMIN")  
                          .requestMatchers(PathRequest.toStaticResources().atCommonLocations())  
                              .permitAll()  
                          .antMatchers("/")  
                              .permitAll()  
                          .antMatchers("/\*\*")  
                              .authenticated()  
                          .and()  
                          .httpBasic();  
              }  
          }

          application.properties的相關(guān)配置如下:

          # Spring Security Default user name and password  
          spring.security.user.name=actuator
          spring.security.user.password=actuator
          spring.security.user.roles=ACTUATOR_ADMIN

          結(jié)語

          本篇文章內(nèi)容就到這里,如果不懂或疑問,歡迎加群溝通,或通過我的視頻教程進(jìn)行學(xué)習(xí)!

          瀏覽 69
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精品久久影院 | 久久综合导航 | 成人做爰黄AA片免费看三区 | 国产欧美日韩在线观看 | 亚洲免费一级片 |