豬齒魚的微服務之路(五):微服務的「健康保障」

本文是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對程序的線程指標進行了擴充,添加了 NEW, RUNNABLEBLOCKEDWAITINGTIMED_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-bitfluentd 和 Kibana。對於日誌的採集分為如下幾個步驟。

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

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

  • 故障查找:通過檢索日誌信息,定位相應的 bug ,找出解決方案。
  • 服務分析:通過對日誌信息進行統計、分析,了解服務器的負荷和服務運行狀態。
  • 數據分析:分析數據,對用戶進行行為分析。

寫在最後

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

總結

回顧一下這篇文章,整體介紹了配置中心在微服務架構中的作用,並提出了Choerodon對於配置管理的一些心得和規範。服務配置是服務運行起來的基礎,而配置中心是整個微服務技術體系中的關鍵基礎保障,如何做好服務配置規劃,並推動項目的持續交付,則是Choerodon仍需持續考慮的問題。


本文由豬齒魚技術團隊原創,轉載請註明出處