本文是Choerodon 的微服務系列推文第五篇,上一篇《豬齒魚的微服務之路(四):深入理解微服務配置中心》介紹了配置中心在微服務架構中的作用,本篇將介紹微服務監控的重要性和必要性,
▌文章的主要內容包括:
- 為什么要監控
- 開發者需要監控哪些
- 豬齒魚的解決方案
在前面的幾期的文章里,介紹了在豬齒魚 Choerodon 的微服務架構中,系統被拆分成多個有著獨立部署能力的業務服務,每個服務可以使用不同的編程語言,不同的存盤介質,來保持最低限度的集中式管理,
這樣的架構決定了功能模塊的部署是分布式的,不同的業務服務單獨部署運行的,運行在獨立的容器行程中,彼此之間通過網路進行服務呼叫互動,一次完整的業務流程會經過很多個微服務的處理和傳遞,
在這種情況下,如何監控服務的錯誤和例外,如何快速地定位和處理問題,以及如何在復雜的容器拓撲中篩選出用戶所需要的指標,是 Choerodon 在監控中面臨的首要問題,本文將會分享 Choerodon 在微服務下的監控思考,以及結合社區流行的 Spring Cloud、Kubernetes、Prometheus 等,打造的 Choerodon 的監控方案,
為什么要監控
在談到 Choerodon 的監控之前,大家需要清楚為什么需要微服務下的監控,
傳統的單體應用中,由于應用部署在具體的服務器上,開發者一般會從不同的層級對應用進行監控,比如豬齒魚團隊常用的方式是將監控分成基礎設施、系統、應用、業務和用戶端這幾層,并對每一層分別進行監控,如下圖所示,

而在微服務系統中,開發者對于監控的關心點是一樣的,但是視角卻發生了改變,從分層 + 機器的視角轉化為以服務為中心的視角,在 Choerodon 中,傳統的分層已經不太適用,服務是部署在 k8s 的 pod 中,而不是直接部署在服務器上,團隊除了對服務器的監控之外,還需要考慮到 k8s 中容器的監控,同樣,由于一個業務流程可能是通過一系列的業務服務而實作的,如何追蹤業務流的處理也同樣至關重要,
所以在微服務中,大家同樣離不開監控,有效的監控能夠幫開發者快速的定位故障,保護系統健康的運行,
平開發者需要監控哪些
在 Choerodon 中,將系統的使用人員分為應用的管理人員,開發人員,運維人員,而不同的人員在平臺中所關心的問題則分別不同,
- 作為應用的管理人員,需要查看到系統中各個節點實體的運行狀態以及實體中應用的狀態,
- 作為開發人員,需要查看自己開發的服務在運行中的所有資訊,也需要跟蹤請求流的處理順序和結果,并快速定位問題,
- 作為運維人員,需要查看系統集群中服務器的 CPU、記憶體、堆疊等資訊,需要查看K8S集群的運行狀態,同時也需要查看各個服務的運行日志,
除了這些以外,還需要監控到如下的一些資訊:
- 服務的概覽資訊:服務的名稱,相關的配置等基本資訊,
- 服務的拓撲關系:服務之間的呼叫關系,
- 服務的呼叫鏈:服務之間的請求呼叫鏈,
- 服務的性能指標:服務的CPU,記憶體等,
- 介面的呼叫監控:介面的吞吐量,錯誤率,回應時間等,
- 服務的日志資料:服務運行中產生的日志例外,
簡而概之,對于 Choerodon 而言,開發者將監控聚焦在指標監控,呼叫監控和日志監控,
豬齒魚的解決方案
在社區中,有很多對監控的解決方案,比如指標監控有 Prometheus,鏈路監控有 zipkin、pinpoint,skywalking,日志則有 elk,
Choerodon 具有多集群多環境管理能力,Choerodon 為需要監控的集群配置監控組件,并與Choerodon 所在集群的監控組件互通以及過濾多余資料,可以最大限度地減少多集群非同一局域網的外網帶寬需求,在多集群環境中仍然可以感知所管理應用的運行狀態和配置預警資訊,

▌指標監控
Spring Boot 的執行器包含一系列的度量指標(Metrics)介面,當你請求 metrics 端點,你可能會看到類似以下的回應:
{
"counter.status.200.root": 20,
"counter.status.200.metrics": 3,
"counter.status.200.star-star": 5,
"counter.status.401.root": 4,
"gauge.response.star-star": 6,
"gauge.response.root": 2,
"gauge.response.metrics": 3,
"classes": 5808,
"classes.loaded": 5808,
"classes.unloaded": 0,
"heap": 3728384,
"heap.committed": 986624,
"heap.init": 262144,
"heap.used": 52765,
"nonheap": 0,
"nonheap.committed": 77568,
"nonheap.init": 2496,
"nonheap.used": 75826,
"mem": 986624,
"mem.free": 933858,
"processors": 8,
"threads": 15,
"threads.daemon": 11,
"threads.peak": 15,
"threads.totalStarted": 42,
"uptime": 494836,
"instance.uptime": 489782,
"datasource.primary.active": 5,
"datasource.primary.usage": 0.25
}
這些系統指標具體含義如下:
- 系統記憶體總量(mem),單位:KB
- 空閑記憶體數量(mem.free),單位:KB
- 處理器數量(processors)
- 系統正常運行時間(uptime),單位:毫秒
- 應用背景關系(應用實體)正常運行時間(instance.uptime),單位:毫秒
- 系統平均負載(systemload.average)
- 堆資訊(heap,heap.committed,heap.init,heap.used),單位:KB
- 執行緒資訊(threads,thread.peak,thead.daemon)
- 類加載資訊(classes,classes.loaded,classes.unloaded)
- 垃圾收集資訊(gc.xxx.count, gc.xxx.time)
有了這些指標,我們只需要做簡單的修改,就可以使這些指標被 Prometheus 所監測到,Prometheus 是一套開源的系統監控報警框架,默認情況下 Prometheus 暴露的metrics endpoint為/prometheus,
在專案的pom.xml檔案中添加依賴,該依賴包含了 micrometer 和 prometheus 的依賴,并對監控的指標做了擴充,
<dependency>
<groupId>io.choerodon</groupId>
<artifactId>choerodon-starter-hitoa</artifactId>
<version>${choerodon.starters.version}</version>
</dependency>
Prometheus提供了4中不同的Metrics型別:Counter,Gauge,Histogram,Summary,通過Gauge,Choerodon對程式的執行緒指標進行了擴充,添加了 NEW, RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED 這幾種型別,具體代碼如下,
@Override
public void bindTo(MeterRegistry registry) {
Gauge.builder("jvm.thread.NEW.sum", threadStateBean, ThreadStateBean::getThreadStatusNEWCount)
.tags(tags)
.description("thread state NEW count")
.register(registry);
Gauge.builder("jvm.thread.RUNNABLE.sum", threadStateBean, ThreadStateBean::getThreadStatusRUNNABLECount)
.tags(tags)
.description("thread state RUNNABLE count")
.register(registry);
Gauge.builder("jvm.thread.BLOCKED.sum", threadStateBean, ThreadStateBean::getThreadStatusBLOCKEDCount)
.tags(tags)
.description("thread state BLOCKED count")
.register(registry);
Gauge.builder("jvm.thread.WAITING.sum", threadStateBean, ThreadStateBean::getThreadStatusWAITINGCount)
.tags(tags)
.description("thread state WAITING count")
.register(registry);
Gauge.builder("jvm.thread.TIMEDWAITING.sum", threadStateBean, ThreadStateBean::getThreadStatusTIMEDWAITINGCount)
.tags(tags)
.description("thread state TIMED_WAITING count")
.register(registry);
Gauge.builder("jvm.thread.TERMINATED.sum", threadStateBean, ThreadStateBean::getThreadStatusTERMINATEDCount)
.tags(tags)
.description("thread state TERMINATED count")
.register(registry);
}
▌呼叫監控
在微服務架構中,一個請求可能會涉及到多個服務,請求的路徑則可能構成一個網狀的呼叫鏈,而如果其中的某一個節點發生例外,則整個鏈條都可能受到影響,

針對這種情況,團隊需要有一款呼叫鏈監控的工具,來支撐系統監控分布式的請求追蹤,目前社區中有一些工具:Zipkin、Pinpoint、SkyWalking,Choerodon 使用的是 SkyWalking,它是一款國產的 APM 工具,包括了分布式追蹤、性能指標分析、應用和服務依賴分析等,
Skywalking 包含 Agent 和 Collecter,具體的部署和原理在這里不在做具體的介紹,Choerodon 的服務在每個服務的 DockerFile中,添加了對 Skywalking Agent 的支持,具體如下:
FROM registry.cn-hangzhou.aliyuncs.com/choerodon-tools/javabase:0.7.1
COPY app.jar /iam-service.jar
ENTRYPOINT exec java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap $JAVA_OPTS $SKYWALKING_OPTS -jar /iam-service.jar
部署時通過配置容器的環境變數 SKYWALKING_OPTS 來實作客戶端的配置,
▌日志監控
日志是程式在運行中產生的遵循一定格式(通常包含時間戳)的文本資料,通常由Choerodon的服務生成,輸出到不同的檔案中,一般會有系統日志、應用日志、安全日志等等,這些日志分散地存盤在不同的容器、機器中,當開發者在排查故障的時候,日志會幫助他們快速地定位到故障的原因,
Choerodon 采用了業界通用的日志資料管理解決方案,主要包括elasticsearch、fluent-bit、fluentd 和 Kibana,對于日志的采集分為如下幾個步驟,

- 日志收集:通過 fluent-bit 讀取 k8s 集群中 cluster 的日志,并進行收集,
- 日志過濾:通過 fluentd 將讀取到的日志進行過濾,并進行快取,
- 日志存盤:將過濾后的日志存盤至 elasticsearch 集群中,
- 日志展示:通過 kibana 查詢 elasticsearch 中的日志資料,并用于展示,
通過端對端可視化的日志集中管理,給開發團隊帶來如下的一些好處:
- 故障查找:通過檢索日志資訊,定位相應的 bug ,找出解決方案,
- 服務分析:通過對日志資訊進行統計、分析,了解服務器的負荷和服務運行狀態,
- 資料分析:分析資料,對用戶進行行為分析,
寫在最后
回顧一下這篇文章,介紹了微服務監控的重要性和必要性,以及 Choerodon 是如何應對指標監控,呼叫監控和日志監控這三種監控的,微服務架構下的服務規模大,系統相對復雜,也使得眾多開發者成為了微服務的受害者,如何做好微服務下的監控,保障系統健康地運行,我們仍有許多需要繼續努力的,
總結
回顧一下這篇文章,整體介紹了配置中心在微服務架構中的作用,并提出了Choerodon對于配置管理的一些心得和規范,服務配置是服務運行起來的基礎,而配置中心是整個微服務技術體系中的關鍵基礎保障,如何做好服務配置規劃,并推動專案的持續交付,則是Choerodon仍需持續考慮的問題,
本文由豬齒魚技術團隊原創,轉載請注明出處
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/412998.html
標籤:其他
