Spring Boot應用的健康監控

本文首發於我的網站:Spring Boot應用的健康監控html

在以前的系列文章中咱們學習瞭如何進行Spring Boot應用的功能開發,以及如何寫單元測試、集成測試等,然而,在實際的軟件開發中須要作的不只如此:還包括對應用程序的監控和管理。java

正如飛行員不喜歡盲目飛行,程序員也須要實時看到本身的應用目前的運行狀況。若是給定一個具體的時間,咱們但願知道此時CPU的利用率、內存的利用率、數據庫鏈接是否正常以及在給定時間段內有多少客戶請求等指標;不只如此,咱們但願經過圖表、控制面板來展現上述信息。最重要的是:老闆和業務人員但願看到的是圖表,這些比較直觀易懂。程序員

首先,這篇文章講介紹如何定製本身的health indicator。web

實戰

  • 在pom文件中添加spring-boot-starter-actuator依賴
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  • spring-boot-starter-actuator這個庫讓咱們能夠訪問應用的不少信息,包括:/env、/info、/metrics、/health等。如今運行程序,而後在瀏覽器中訪問:http://localhost:8080/health,將能夠看到下列內容。acatuator庫提供監控信息
  • 除了/health能夠訪問,其餘的Endpoints也能夠訪問,例如/info:首先在application.properties文件中添加對應的屬性值,符號*@*包圍的屬性值來自pom.xml文件中的元素節點。
info.build.artifact=@project.artifactId@
info.build.name=@project.name@
info.build.description=@project.description@
info.build.version=@project.version@
  • 要獲取配置文件中的節點值,須要在pom文件中進行必定的配置,首先在<build>節點裏面添加:
<resources>
   <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
   </resource>
</resources>

而後在<plugins>節點裏面增長對應的插件:面試

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-resources-plugin</artifactId>
   <version>2.6</version>
   <configuration>
      <delimiters>
         <delimiter>@</delimiter>
      </delimiters>
      <useDefaultDelimiters>false</useDefaultDelimiters>
   </configuration>
</plugin>
  • 而後運行應用程序,訪問http://localhost:8080/info,能夠看到下列信息 http://localhost:8080/info
  • 除了使用系統默認的監控信息,咱們還能夠定義本身的health indicator。使用Spring Boot:定製本身的starter一文中作過的db-count-starter做爲觀察對象,咱們但願監控每一個數據庫接口的運行情況:若是某個接口返回的個數大於等於0,則表示系統正常,表示爲UP狀態;不然,可能該接口發生異常,表示爲DOWN狀態。首先,將DbCountRunner類中的getRepositoryName方法由private轉爲protected,而後在db-count-starter這個模塊中也添加actuator依賴。
  • db-count-starter/src/main/com/test/bookpubstarter目錄下建立DbCountHealthIndicator.java文件
public class DbCountHealthIndicator implements HealthIndicator {
    private CrudRepository crudRepository;
    public DbCountHealthIndicator(CrudRepository crudRepository) {
        this.crudRepository = crudRepository;
    }
    @Override
    public Health health() {
        try {
            long count = crudRepository.count();
            if (count >= 0) {
                return Health.up().withDetail("count", count).build();
            } else {
                return Health.unknown().withDetail("count", count).build();
            }
        } catch (Exception e) {
            return Health.down(e).build();
        }
    }
}
  • 最後,還須要註冊剛剛建立的健康監控器,在DbCountAutoConfiguration.java中增長以下定義:
@Autowired
private HealthAggregator healthAggregator;
@Bean
public HealthIndicator dbCountHealthIndicator(Collection<CrudRepository> repositories) {
    CompositeHealthIndicator compositeHealthIndicator = new
            CompositeHealthIndicator(healthAggregator);
    for (CrudRepository repository: repositories) {
        String name = DbCountRunner.getRepositoryName(repository.getClass());
        compositeHealthIndicator.addHealthIndicator(name, new DbCountHealthIndicator(repository));
    }
    return compositeHealthIndicator;
}

自定義的health indicator

分析

Spring Boot Autuator這個庫包括不少自動配置,對外開放了不少endpoints,經過這些endpoints能夠訪問應用的運行時狀態:spring

  • /env提供應用程序的環境變量,若是你在調試時想知道某個配置項在運行時的值,能夠經過這個endpoint訪問——訪問http://localhost:8080/env,能夠看到不少方面的配置,例如,class path resources—[tomcat.https.properties]、applicationConfig—[classpath:/application.properties]、commonsConfig、systemEnvironment、systemProperties等。 這些變量的值由Environment實例中的PropertySource實例保存,根據這些屬性值所在的層次,有可能在運行時已經作了值替換,跟配置文件中的不同了。爲了確認某個屬性的具體值,例如book.count.rate屬性,能夠訪問http://localhost:8080/env/book.counter.rate來查詢,若是跟配置文件中的不同,則多是被系統變量或者命令行參數覆蓋了。EnvironmentEndpoint類負責實現上述功能,有興趣能夠再看看它的源碼;
  • /configprops提供不一樣配置對象,例如WebConfiguration.TomcatSslConnectionProperties,它與/env不一樣的地方在於它會表示出與配置項綁定的對象。嘗試下訪問http://localhost:8080/configprops,而後在網頁中查詢custom.tomcat.https,能夠看到咱們以前用於配置TomcatSslConnector對象的屬性值(參見:讓你的Spring Boot工程支持HTTP和HTTPS)。 TomcatSslConnector對應的屬性值
  • /autoconfig以web形式對外暴露AutoConfiguration 信息,這些信息的解釋能夠參考Spring Boot:定製本身的starter一文,這樣咱們就不須要經過「修改應用程序的日誌級別和查看應用的啓動信息」來查看應用的自動配置狀況了。
  • /beans,這個endpoint列出全部由Spring Boot建立的bean。 /beans顯示全部Spring Boot建立的bean
  • /mapping,這個endpoint顯示當前應用支持的URL映射,該映射關係由HandlerMapping類維護,經過這個endpoint能夠查詢某個URL的路由信息。 /mappings查看URL映射
  • /info,這個endpoint顯示應用程序的基本描述,在以前的實踐例子中咱們看過它的返回信息,屬性值來自appliaction.properties,同時也可使用佔位符獲取pom.xml文件中的信息。任何以info.開頭的屬性都會在訪問http://localhost:8080/info時顯示。
  • /health提供應用程序的健康狀態,或者是某個核心模塊的健康狀態。
  • /metrics,這個endpoint顯示Metrics 子系統管理的信息,後面的文章會詳細介紹它。

上述各個endpoint是Spring Boot Actuator提供的接口和方法,接下來看看咱們本身定製的HealthIndicator,咱們只須要實現HealthIndicator接口,Spring Boot會收集該接口的實現,並加入到*/health*這個endpoint中。數據庫

在咱們的例子中,咱們爲每一個CrudRepository實例都建立了一個HealthIndicator實例,爲此咱們建立了一個CompositeHealthIndicator實例,由這個實例管理全部的DbHealthIndicator實例。做爲一個composite,它會提供一個內部的層次關係,從而能夠返回JSON格式的數據。apache

代碼中的HealthAggregator實例的做用是:它維護一個map,告訴CompositeHealthIndicator如何決定全部HealthIndicator表明的總體的狀態。例如,除了一個repository返回DOWN其餘的都返回UP,這時候這個composite indicator做爲一個總體應該返回UP仍是DOWN,HealthAggregator實例的做用就在這裏。後端

Spring Boot使用的默認的HealthAggregator實現是OrderedHealthAggregator,它的策略是手機全部的內部狀態,而後選出在DOWN、OUT_OF_SERVICE、UP和UNKNOWN中間具備最低優先級的那個狀態。這裏使用策略設計模式,所以具體的狀態斷定策略能夠改變和定製,例如咱們能夠建立定製的HealthAggregator設計模式

最後須要考慮下安全問題,經過這些endpoints暴露出不少應用的信息,固然,Spring Boot也提供了配置項,能夠關閉指定的endpoint——在application.properties中配置*<name>.enable=false*;

還能夠經過設置management.port=-1關閉endpoint的HTTP訪問接口,或者是設置其餘的端口,供內部的admin服務訪問;除了控制端口,還能夠設置僅僅讓本地訪問,只須要設置management.address=127.0.0.1;經過設置management.context-path=/admin,能夠設置指定的根路徑。綜合下,通過上述設置,在本地訪問http://127.0.0.1/admin/health來訪問健康狀態。

能夠在防火牆上屏蔽掉不是/admin/*的endpoints訪問請求,更進一步,利用Spring Security能夠配置驗證信息,這樣要訪問當前應用的endpoints必須使用用戶名和密碼登錄。

參考資料

  1. Endpoints
  2. Complete Guide for Spring Boot Actuator

Spring Boot 1.x系列

  1. Spring Boot的自動配置、Command-line-Runner
  2. 瞭解Spring Boot的自動配置
  3. Spring Boot的@PropertySource註解在整合Redis中的使用
  4. Spring Boot項目中如何定製HTTP消息轉換器
  5. Spring Boot整合Mongodb提供Restful接口
  6. Spring中bean的scope
  7. Spring Boot項目中使用事件派發器模式
  8. Spring Boot提供RESTful接口時的錯誤處理實踐
  9. Spring Boot實戰之定製本身的starter
  10. Spring Boot項目如何同時支持HTTP和HTTPS協議
  11. 自定義的Spring Boot starter如何設置自動配置註解
  12. Spring Boot項目中使用Mockito
  13. 在Spring Boot項目中使用Spock測試框架
  14. Spring Boot項目中如何定製攔截器
  15. Spring Boot項目中如何定製PropertyEditors
  16. Spring Boot構建的Web項目如何在服務端校驗表單輸入

本號專一於後端技術、JVM問題排查和優化、Java面試題、我的成長和自我管理等主題,爲讀者提供一線開發者的工做和成長經驗,期待你能在這裏有所收穫。javaadu

相關文章
相關標籤/搜索