Java程式設計微服務架構框架-監控與管理(SpringBoot)

歐陽慍斐發表於2018-07-06

       在微服務架構中,我們將原本龐大的單體系統拆分成多個提供不同服務的應用。 雖然 各個應用的內部邏輯因分解而得以簡化,但是由於部署應用的數量成倍增長,使得系統的 維護複雜度大大提升。 對於運維人員來說,隨著應用的不斷增多,系統叢集中出現故障的 頻率也變得越來 越高,雖然在高可用機制的保護下,個別故障不會影響系統的對外服務, 但是這些頻繁出現的故障需要被及時發現和處理才能長期保證系統處千健康可用狀態。 為 了能對這些成倍增長的應用做到高效運維,傳統的運維方式顯然是不合適的,所以我們需 要實現一套自動化的監控 運維機制,而這套機制的執行基礎就是不間斷地收集各個微服務 應用的各項 指標情況,並根據這些基礎指標資訊來制定監控和預警規則,更進一步甚至做 到一些自動化的運維操作等。

  為了讓運維繫統能夠獲取各個微服務應用的相關指標以及實現一些常規操作控制,我 們需要開發一套專門用於植入各個微服務應用的介面供監控 系統採集資訊。 而這些介面往 往有很大一 部分指標都是類似的, 比如環境變數、 垃圾收集資訊、 記憶體資訊、 執行緒池資訊 等。 既然這些資訊那麼通用,難道就沒有一個標準化的實現框架嗎?

  當我們決定用Spring Boot來作為微服務框架時,除了它強大的快速開發功能之外,還因 為它在Starter POMs中提供了一個特殊依賴模組spring-boot-starter-actuator 。引入該模組能夠自動為 Spring Boot 構建的應用提供 一系列用千監控的端點。 同時, Spring Cloud 在實現各個微服務元件的時候, 進 一步為該模組做了不少擴充套件, 比如, 為原生端點 增加了更多的指標和度量資訊(比如在整合 Eureka 的時候會為/health 端點增加相關的 資訊), 並且根據不同的元件還提供了更多有空的端點(比如, 為 API 閘道器元件 Zuul 提供 了 /routes 端點來返回路由資訊)。

  spring-boot-starter-actuator 模組的實現對千實施微服務的中小團隊來說, 可以有效地省去或大大減少監控系統在採集應用指標時的開發量。 當然, 它也並不是萬能 的, 有時候也需要對其做 一些簡單的擴充套件來幫助我們實現自身系統個性化的監控需求。 所 以,在本節將詳細介紹一些關於spring-boot-starter-actuator模組的內容, 包括 原生提供的端點以及一些常用的擴充套件和配置方式等。

  在現有 的 Spring Boot 應用中引入該模組非常簡單 , 只需要 在 pom.xml 的 dependency 節點中,新增 spring-boot-starter-actua七or 的依賴即可,具體如下:

  <dependency>

  <groupId>org.springframework.boot</groupId>

  <artifactId>spring-boot-starter-actuator</artifactId>

  </dependency>

  增加該依賴之後,重新啟動應用。此時,我們可以在控制檯中看到如下圖所示的輸出:

  : Mapped “{[/trace i I /trace.json],methods=(GET),produces=[applicat10n

  : Mapped “{[/info 11 /info.json],methods=[GET},produces=[application/j

  : Mapped ” { [ / env / {name: , }], methods=[ GET), produces= [ application/json)}

  : Mapped “{[/env 11 /env.json],methods=[GET),produces=[application/jso

  : Mapped “{[/dump 11 /dump.json],methods=[GET),produces=[application/j, Mapped “([/autoconfig 11 /autoconfig.json],rnethods=[GET),produces=[a

  : Mapped “{[/health 11 /health.json],produces=[application/json)}” ont

  : Mapped “{[/mappings 11 /mappings.json],methods=(GET],produces=(appli

  : Mapped “{[/beans 11 /beans.json],methods=[GET),produces=[application

  : Mapped “{[/configprops 11 /configprops.json],methods=[GET),produces=

  : Mapped “{[/metrics/{name:. 不}],methods=(GET),produces=[application/js

  : Mapped “{[/metrics 11 /metrics.json],methods=[GET),produces=(applica

  原生端點

  通過在快速入門示例中新增spring-boot-starter-actuator模組, 我們已經對 它有了 一個初步的認識。接下來,我們詳細介紹一下 spring-boot-starter-actuator模組中已經實現的一些原生端點。 根據端點的作用, 可以將原生端點分為以下三大類。

  應用配置類:獲取應用程式中載入的應用配置、 環境變數、 自動化配置報告等與 Spring Boot應用密切相關的配置類資訊。

  度最指標類:獲取應用程式執行過程中用於監控的度量指標, 比如記憶體資訊、 執行緒 池資訊、 HTTP請求統計等。

  操作控制類:提供了對應用的關閉等操作類功能。

  1、應用配置類->由於SpringBoot為了改善傳統Spring應用繁雜的配置內容,採用了包掃描和自動化配 置的機制來載入原本集中於XML檔案中的各項內容。 雖然這樣的做法讓我們的程式碼變得 非常簡潔,但是整個應用的例項建立和依賴關係等資訊都被離散到了各個配置類的註解上, 這使我們分析整個應用中資源和例項的各種關係變得非常困難。 而這類端點可以幫助我們 輕鬆獲取一系列關於 Spring 應用配置內容的詳細報告, 比如自動化配置的報告、 Bean創 建的報告、 環境屬性的報告等。

  /autoconfig:該端點用來獲取應用的自動化配置報告, 其中包括所有自動化配置的 候選項。 同時還列出了每個候選項是否滿足自動化配置的各個先決條件。 所以, 該 端點可以幫助我們方便地找到一些自動化配置為什麼沒有生效的具體原因。 該報告 內容將自動化配置內容分為以下兩部分。

  positiveMatches中返回的是條件匹配成功的自動化配置。

  negativeMatches中返回的是條件匹配不成功的自動化配置。

  /beans:該端點用來獲取應用上下文中建立的所有Bean。

  Bean 中都包含了下面這些資訊:

  bean: Bean 的名稱。

  scope: Bean 的作用域。

  type: Bean 的 Java 型別。

  resource: class 檔案的具體路徑。

  dependencies: 依賴的 Bean 名稱。

  /configprops:該端點用來獲取應用中配置的屬性資訊報告。 從下面該端點返回示例 的片段中, 我們看到返回了關於該簡訊的配置資訊, prefix 屬性代表了屬性的配 置字首, properties 代表了各個屬性的名稱和值。 所以, 我們可以通過該報告來 看 到各個屬性的 配 置路 徑, 比如我們要關閉該端點, 就可 以 通過使用 endpoints.configprops.enabled=false 來完成設定。

  /env: 該端點與/configprops不同它用來獲取應用所有可用的環境屬性報告。 包括 環境變數、NM屬性、應用的配置屬性、命令列中的引數。 從下面該端點返回的示 例片段中, 可以看到它不僅返回了應用的配置屬性, 還返回了系統屬性、環境變數 等豐富的配置資訊, 其中還包括了應用還沒有使用的配置, 所以它可以幫助我們方 便地看到當前應用可以載入的配置資訊, 並配合@ConfigurationProperties 註解將它們引入到我們的應用程式中來進行使用。 另外, 為了配置屬性的安全, 對 於一些類似密碼等敏感資訊, 該端點都會進行隱私保護, 但是我們需要讓屬性名中 包含password、secret、key這些關鍵詞, 這樣該端點在返回它們的時候會使用*來替代實際的屬性值。

  /mappings: 該端點用來返回所有Spring MVC的控制器對映關係報告。 從下面的示 例片段中, 我們可以看到該報告的資訊與我們在啟用Spring MVC的Web應用時輸 出的日誌資訊類似, 其中bean屬性標識了該對映關係的請求處理器, method屬 性標識了該對映關係的具體處理類和處理函式。

  /info: 該端點用來返回一些應用自定義的資訊。 預設清況下, 該瑞點只會返回 一個 空的JSON內容。我們可以在application.properties配置檔案中通過info 字首來設定一些屬性, 比如下面這樣: info.app.name=spring-boot-hello

  info.app.version=vl.0.0

  再訪問/info端點我們可以得到下面的返回報告, 其中就包含了上面我們在應用 中自定義的兩個引數。

  ”app”: {

  ”name”: “spring-boot-hello”,

  ”version”: “vl.0.0”

  }

  2、度量指標類–>上面我們所介紹的應用配置類端點所提供的資訊報告在應用啟動的時候就已經基本確 定了其返回內容, 可以說是一個靜態報告。 而度量指標類端點提供的報告內容則是動態變 化的,這些端點提供了應用程式在執行過程中的一些快照資訊,比如記憶體使用情況、 HTTP 請求統計、外部資源指標等。這些端點對於我們構建微服務架構中的監控系統非常有幫助, 由於 Spring Boot 應用自身實現了這些端點,所以我們可以很方便地利用它們來收集我們想 要的資訊, 以制定出各種自動化策略。

  /metrics: 該端點用來返回當前應用的各類重要度量指標,比如記憶體資訊、執行緒資訊、 垃圾回收資訊等。

  {

  ”mem”:1292717,

  ”mem.free”:703542,

  ”processors”:32,

  ”instance.uptime”:245161086,

  ”uptime”:245165938,

  ”systemload.average”:0,

  ”heap.committed”:1238016,

  ”heap.init”:1026744,

  ”heap.used”:534473,

  ”heap”:14603776,

  ”nonheap.committed”:55232,

  ”nonheap.init”:24000,

  ”nonheap.used”:54701,

  ”nonheap”:133120,

  ”threads.peak”:28,

  ”threads.daemon”:23,

  ”threads.totalStarted”:296,

  ”threads”:26,

  ”classes”:8854,

  ”classes.loaded”:8854,

  ”classes.unloaded”:0,

  ”gc.ps_scavenge.count”:4,

  ”gc.ps_scavenge.time”:163,

  ”gc.ps_marksweep.count”:0,

  ”gc.ps_marksweep.time”:0,

  ”httpsessions.max”:-1,

  ”httpsessions.active”:0,

  ”counter.status.200.aliPay.createOrderANdAliPayUrl”:4,

  ”counter.status.200.aliPay.notifyUrl”:2,

  ”counter.status.200.atOnceWithhold”:12,

  ”counter.status.200.autoconfig”:1,

  ”counter.status.200.metrics”:1,

  ”counter.status.200.withhold”:254,

  ”counter.status.405.unmapped”:2,

  ”gauge.response.aliPay.createOrderANdAliPayUrl”:35,

  ”gauge.response.aliPay.notifyUrl”:481,

  ”gauge.response.atOnceWithhold”:10046,

  ”gauge.response.autoconfig”:35,

  ”gauge.response.metrics”:19,

  ”gauge.response.unmapped”:6,

  ”gauge.response.withhold”:16

  }

  從上面的示例中, 我們看到有如下這些重要的度量值。

  系統資訊:包括處理器數量processors、執行時間up巨me和instance.uptime、 系統平均負載 systemload.average。

  mem. *: 記憶體概要資訊,包括分配給應用的總記憶體數量以及當前空閒的記憶體數量。 這些資訊來自java.lang.Runtime。

  heap.* : 堆記憶體使用情況。 這些資訊來自 java.lang.management. MemoryMXBean 介面中 getHeapMemoryUsage 方法獲取的 java.lang. management.MemoryUsage。

  nonheap. *: 非堆記憶體使用情況。 這些資訊來自 java. lang.management. MemoryMXBean介面中getNonHeapMemoryUsage方法獲取的java.lang. managemen.MemoryUsage。

  threads.*: 執行緒使用情況,包括執行緒數、守護執行緒數(daemon)執行緒峰值(peak) 等, 這些資料均來自java.lang.management.ThreadMXBean。

  classes.*: 應用載入和解除安裝的類統計。這些資料均來自java.lang.managemen七. ClassLoadingMXBean。

  gc. *: 垃圾收集器的詳細資訊,包括垃圾回收次數gc.ps—scavenge.coun七、 垃圾回收消耗時間 gc.ps_scavenge.time、 標記-清除演算法的次數 gc.ps marksweep.count、 標記-清除演算法的消耗時間gc.ps_marksweep.time。 這些資料均來自java.lang.managemen.GarbageCollectorMXBean。

  httpsessions. * : Tomcat容 器 的會話使用情況。 包 括最大會話 數 httpsessions.max和活躍會話數httpsessions.active。 該度量指標信 息僅在引入嵌入式Tomcat作為應用容器的時候才會提供。

  gauge.*: HTTP請求的效能指標之一,它主要用來反映一個絕對數值。 比如上 面示例中的gauge.response.hello: 5, 它表示上 一 次hello請求的延遲 時間為5毫秒。

  counter.*: HTTP 請求的效能指標之一,它主要作為計 數器來使用,記錄了 增加量和減少量。 上述示例中的counter.status.200.hello: 11, 它代表 了 hello請求返回200狀態的次數為11。

  /metrics端點可以提供應用執行狀態的完整度量指標報告,這項功能 非常實用,但是 對千監控系 統中的各項監控功能,它們的監控內容、 資料收集頻率都有所不同,如 果每次都通過全量獲取報告的方式來收集,略顯粗暴。 所以,我們還可以通過 /metrics/{name}介面來更細粒度地獲取度量資訊 , 比 如可 以通 過訪 問 /metrics/mem.free來獲取當前可用 記憶體數量。

  curl -i http://****:8081/metrics/mem.free

  {

  ”mem.free”:1447714

  }

  喜歡的請關注筆者,後續筆者將持續更新,筆者如果有寫誤的也請評論留言,謝謝!

歡迎工作一到五年的Java工程師朋友們加入Java架構開發:468947140

點選連結加入群聊【Java-BATJ企業級資深架構】:https://jq.qq.com/?_wv=1027&k=5zMN6JB

本群提供免費的學習指導 架構資料 以及免費的解答

不懂得問題都可以在本群提出來 之後還會有職業生涯規劃以及面試指導


相關文章