1. 程式人生 > >Choerodon 的微服務之路(五):微服務的“健康保障”

Choerodon 的微服務之路(五):微服務的“健康保障”

開發十年,就只剩下這套架構體系了! >>>   

本文是Choerodon 的微服務系列推文第五篇,上一篇《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型別:CounterGaugeHistogramSummary。通過Gauge,Choerodon對程式的執行緒指標進行了擴充,添加了 NEWRUNNABLEBLOCKEDWAITINGTIMED_WAITINGTERMINATED 這幾種型別,具體程式碼如下。

@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 採用了業界通用的日誌資料管理解決方案,主要包括elasticsearchfluent-bitfluentdKibana。對於日誌的採集分為如下幾個步驟。

  • 日誌收集:通過 fluent-bit 讀取 k8s 叢集中 cluster 的日誌,並進行收集。
  • 日誌過濾:通過 fluentd 將讀取到的日誌進行過濾,並進行快取。
  • 日誌儲存:將過濾後的日誌儲存至 elasticsearch 叢集中。
  • 日誌展示:通過 kibana 查詢 elasticsearch 中的日誌資料,並用於展示。

通過端對端視覺化的日誌集中管理,給開發團隊帶來如下的一些好處:

  • 故障查詢:通過檢索日誌資訊,定位相應的 bug ,找出解決方案。
  • 服務分析:通過對日誌資訊進行統計、分析,瞭解伺服器的負荷和服務執行狀態。
  • 資料分析:分析資料,對使用者進行行為分析。

寫在最後

回顧一下這篇文章,介紹了微服務監控的重要性和必要性,以及 Choerodon 是如何應對指標監控,呼叫監控和日誌監控這三種監控的。微服務架構下的服務規模大,系統相對複雜,也使得眾多開發者成為了微服務的受害者。如何做好微服務下的監控,保障系統健康地執行,我們仍有許多需要繼續努力的。

更多關於微服務系列的文章,點選藍字即可閱讀 ▼

關於Choerodon豬齒魚

Choerodon豬齒魚作為開源多雲應用平臺,是基於Kubernetes的容器編排和管理能力,整合DevOps工具鏈、微服務和移動應用框架,來幫助企業實現敏捷化的應用交付和自動化的運營管理,同時提供IoT、支付、資料、智慧洞察、企業應用市場等業務元件,致力幫助企業聚焦於業務,加速數字化轉型。

大家也可以通過以下社群途徑瞭解豬齒魚的最新動態、產品特性,以及參與社群貢獻:

歡迎加入Choerodon豬齒魚社群,共同為企業數字化服務打造一個開