淺談云原生可觀測性
背景
當前數字化轉型進程持續加速中,在頂層設計指導下,結合自身發展需要,全面推廣一朵全棧云,深化云原生生態建設,推動業務應用大量采用微服務、容器等云原生技術,基于DevOps模式進行研發,將傳統的單體服務拆分成粒度更細的微服務模塊,使系統可以更好地適配容器化部署,更好地進行敏捷的業務迭代研發,快速輸出系統業務價值。
云原生建設是一個綜合性的系統工程,涉及微服務重構、國產信創、分布式數據庫、容器云、服務治理等多個方面,系統規模和復雜度以及數據量成倍提升,可能發生故障的數量和類型也同比提升,全面有效的保障服務持續穩定運行至關重要,云原生安全運營是當下面臨的重要課題。
面臨的挑戰
要保障服務安全運營,首先必須要能全面理解系統運行的狀態和行為,這要求實現從底層到上層對網絡、主機、容器、應用、業務服務等進行全棧可觀測。可觀測性(observability)最早來源于控制理論領域,指的是系統可以由其外部輸出推斷其內部狀態的程度。在云原生架構中,可觀測性描述的是對系統中所發生情況的掌握程度。云原生系統規模大、系統復雜、動態變化,對其進行全面、有效的理解和掌控,以及保障安全運營方面面臨著巨大的挑戰:
如何理解大規模動態容器環境中應用的實際運行情況:云原生系統通過容器化技術對基礎設施進行了標準化,提升了應用部署的便利性,并支持動態擴縮容。基礎設施層的信息通過虛擬化封裝不再透明,微服務化架構使應用部署的服務數量急劇增加,容器集群根據業務運行情況動態調度。服務間流量既有南北向,也有東西向,且以東西向為主。在這樣大規模動態服務實例的環境中,有效全面理解從應用、容器、主機到網絡的運行情況,是保障業務安全運營的關鍵。
如何在復雜的服務調用間快速定位故障:單體服務拆分成微服務后,模塊間的交互由進程內的方法函數調用轉變為進程間的服務調用,導致服務的調用路徑變長且跨越網絡交互,當發生錯誤時怎樣快速定位故障點,及時采取流量切換、服務回退等措施,是保障服務持續運行的關鍵;不同服務模塊在整個系統中承擔的功能不同,請求壓力也不同,當系統出現性能瓶頸時,怎樣快速發現出現瓶頸的服務并進行服務擴容,或者及時采取熔斷限流措施,是保障服務穩定運行的關鍵。
如何保證觀測能力的實時性:云原生應用的動態性要求可觀測性平臺必須具備實時性或近實時性。如果應用的升級或擴容在分鐘級完成,那么監測系統就必須提供秒級的反饋能力。云原生系統產生的指標、追蹤、日志等數據往往是海量的,因此對可觀測性平臺實時處理海量數據的能力提出了極高要求。
如何實現多個運維平臺的有機整合:云原生生態涉及多個支撐系統,各系統的有機協調運行才能共同構成云原生運行平臺,但現實是各個運維工具平臺由不同時期、不同產品、不同廠商建設,怎樣將這些運維工具平臺的數據進行有效的治理,實現數據關聯整合,充分發揮數據的價值,實現運維的全景運行、有機協調,是對運維數據治理能力的巨大挑戰。
針對上述云原生架構帶來的新問題與挑戰,我們將嘗試設計一套整體的云原生可觀測性平臺來解決上述擔憂。
可觀測平臺設計
可觀測性平臺方案設計由可觀測運維對象、可觀測數據、數據關聯性、可觀測方案實現四部分組成,涵蓋識別運維對象、可觀測數據標準、不同數據關聯實現,組成整體的可觀測性方案,最后實現價值輸出,具體如下:
可觀測對象
云原生系統可觀測體系需要涵蓋從網絡、主機、容器、應用、業務服務等所有云原生系統的組成部分,根據監控對象在系統中所處的位置,將可觀測體系劃分為四個層次,如圖1所示,涵蓋從系統基礎設施、容器、應用到業務的全范圍,分別為:
圖1 云原生運維棧示意圖
基礎設施層:也即IaaS層,該層涉及的監控對象為系統底層資源,如網絡、存儲設備、裸金屬等。這些設備與組件的可靠性,直接影響到上層應用服務的穩定性。該層關聯的可觀測性數據包含指標(網絡流量、網絡連接數、主機性能)、日志(交換機日志、操作系統日志)、事件(系統平臺事件、故障、宕機)等。
容器層:也即,PaaS層,該層涉及的監控對象涵蓋了容器內的系統資源,如:Kubernetes服務運行情況、集群節點、CPU、內存、存儲等,是針對容器云平臺進行的監控,這些資源的使用情況決定了應用服務的性能和容量。該層關聯的可觀測性數據包含指標(節點或容器的CPU使用率、內存使用率、存儲使用率等)、日志(Kubernetes各個組件日志)、事件(Kubernetes Event)等。
應用層:該層涉及的監控對象和應用服務緊密相關,如:服務可用性、JVM、中間件等,這些監控對象的健康度與負載情況決定了應用之上運行的業務的可用性與性能。該層關聯的可觀測性數據包含指標(服務存活性、JVM內存使用率、JVM GC停頓時長、數據庫連接、緩存連接、消息隊列消息堆積數等)、鏈路(應用服務間調用、應用調用中間件形成的分布式鏈路)、日志(運行日志、錯誤日志)等。
業務層:該層涉及的監控對象主要涉及業務運行信息,如:交易量、交易金額、服務請求量、請求延遲、變化比率、錯誤率等,這些監控指標直接反應業務的運行狀態,體現著用戶體驗與企業發展情況。該層關聯的可觀測性數據包含指標(訪問統計、請求數、錯誤數、延時等)、日志(訪問日志、錯誤日志)。
可觀測數據
可觀測性體系的構建是通過對系統運行狀態數據的收集、分析來判斷系統的運行狀態并實現快速排障。因此,首先要定義可觀測性數據,當前業界主流標準將可觀測性數據分為三個類別:
圖2 Metrics, tracing, logging及關聯關系
指標(metrics):指標數據通常為一段時間內可度量的數據,也被稱為時序數據,用于觀測系統的狀態與趨勢,常用于畫曲線圖。支持以下四種數據:
類型 | 說明 | 示例 |
Counter | 單調遞增的計數器 | http請求總數、QPS、TPS等 |
Gauge | 支持加和減的計數器 | CPU使用率、內存使用值、負載等 |
Histogram | 直方圖 | 對觀察值(如請求持續時間或響應大小)進行采樣,并統計樣本分布,服務端可用于計算分位數(P95、P99)、Apdex指數,如果需要聚合或者觀測值的范圍和分布,可以選擇直方圖。 |
Summary | 分位數 | 百分位(客戶端直接計算),如果需要精確的分位數,選擇Summary。 |
指標數據類型
指標效果展示
鏈路(tracing):分布式追蹤是一種理解分布式系統執行過程中參與的上下游及影響,支持跟蹤應用請求從前端到后端服務以及數據庫等中間件的流轉過程,支持對高延時與高錯誤率的請求進行故障排查。同時從鏈路數據中,可以提取出業務的RED(速率、錯誤、持續時間),豐富指標監控。
Trace路徑感知與性能分析
Trace效果展示
日志(logging):日志數據是離散事件的記錄,反應系統運行過程中產生的信息,可以詳細解釋系統的運行狀態。大多數開發語言、應用程序框架或庫都支持日志。日志可以分為不同的類別,例如系統日志、應用日志、安全日志、基礎設施日志。日志中存儲的信息是無格式的文本,需要制定對應的字段規范以便于后續分析,例如日志包含服務名稱、traceid,并附加采集的容器信息。
日志展示
數據關聯性
可觀測對象雖然劃分為四層,但在實際使用時,通常需要結合多層數據和多個運維工具平臺中的數據一起來分析問題,這就需要觀測數據存在一定關聯性。如下圖所示:
數據關聯性
從數據特性上可以區分為:
同一運維對象關聯
同一運維對象應該具有確定且唯一的標識,在不同數據中(指標、鏈路、日志)應該使用統一的標識標準,用戶可以使用同一套標識分別查詢到不同數據,以方便關聯分析。例如根據Prometheus告警中帶的標簽和時間戳,可以在日志中定位到對應服務在特定時刻的行為,在鏈路中也可以定位到對應服務特定時刻的執行鏈路。
相同運維對象和對應的指標和日志數據
不同運維對象關聯
不同運維對象間的關聯關系比較多樣化,需要具體問題具體分析。在傳統的環境中,我們通常基于IP進行不同主機、網絡節點進行標識和關聯,而在容器云環境中,通常基于標簽標識不同運維對象和資源,不同資源類型不同,但應該具有相同的標簽,這樣才能實現組合。例如Kubernetes中Deployment與Service中的定義必須匹配對應的Labels才能實現匹配和對應功能。
不同運維對象基于標簽識別關聯
鏈路ID關聯
在分布式環境中,應用服務被拆分為不同的服務模塊,一個服務請求會跨越多個不同的運維對象,運維對象也服務于多個不同請求,這種分布式并發性使得如何區分不同請求成為一個難題,這個問題與TCP服務于多個請求的問題類似,HTTP1.1沒有請求標識,無法多路復用,HTT2中加入了流標識才可以,類似的,不同應用間服務請求加入唯一的標識ID即可區分彼此。基于鏈路ID的鏈路跟蹤可以將一次分布式請求還原成調用鏈路,對一次分布式請求的調用情況集中展示,比如各個服務節點上的耗時、請求具體到達哪臺機器上、每個服務節點的請求狀態等等,實現調用拓撲可視化、上下游依賴分析、故障快速定位等。
基于traceid關聯多個運維對象的日志和鏈路
利用上述運維對象和數據的關聯性,并結合梳理的全棧運行環境(圖1),包括基礎設施、容器云平臺、應用和業務信息,構建整體的全景可觀測性拓撲圖,針對不同組件、不同層面的運維對象分別展示不同觀測數據,并與CMDB信息聯動,實現直觀的拓撲信息展示。
全棧監測拓撲示意圖
可觀測實現
可觀測性體系的實現分為三大流程:可觀測性數據采集、可觀測性數據分析、可觀測性數據價值輸出,覆蓋可觀測性數據的產生、采集、處理分析、存儲、應用的全流程。
可觀測性數據采集
數據采集
該流程主要完成可觀測性數據的規范化定義與采集,包括指標、鏈路、日志三類數據。怎樣保證采集數據的完整性以及對應用的無侵入性,是方案需要考慮的關鍵。指標數據為時序數據,數據結構相對固定,在設計時需限制表示業務信息的標簽數量與取值范圍,避免數據量過大,對指標服務端的性能造成影響。針對Kubernetes平臺、業務應用、中間件等,采用服務端拉取的模式進行采集,在相應的服務器上部署獨立的指標采集組件,這些組件負責收集指標數據并通過HTTP協議對外提供指標查詢接口,由指標服務端(如Prometheus)定時調用。針對業務應用,使用Java Agent技術在JVM應用啟動時進行JVM字節碼的增強,在不改變業務代碼的前提下進行JVM性能指標與業務指標的生成,實現監控邏輯與業務邏輯解耦,保證開發流程的擴展性。以上采集過程均能做到對應用無侵入。
為了保證鏈路數據結構相對固定的同時提高數據擴展性,鏈路數據結構采用半結構化的JSON格式。對于鏈路數據,在開發框架中引入鏈路埋點庫。該庫對于服務間調用、服務調用主流中間件(如數據庫、緩存、消息隊列等)等關鍵程序執行位置自動埋點,提供了通用鏈路采集埋點邏輯,引入該開發庫就能自動完成相應位置的鏈路采集。同時提供了手動埋點能力,供開發團隊基于自身業務需求,自定義鏈路埋點代碼以采集特定場景下的鏈路信息。通過無侵入埋點解決通用鏈路采集并結合手動埋點滿足個性化定制需求的方式,在較少代碼侵入的情況下,滿足應用全面鏈路采集的需求。
考慮到日志數據后續解析、處理的統一標準化,業務團隊需制訂并實施標準化的日志數據結構規范。對于日志數據,采用獨立組件上報的模式進行采集,在相應的服務器上部署獨立的日志采集組件(如Filebeat、Flunetbit),負責完成本地日志數據的讀取、上報日志服務端(如ElasticSearch、Loki、ClickHouse)。日志采集組件使用通用的采集配置模板,以便運維人員快速修改進行本地日志采集,提升日志接入監控的效率,并于開發約定雙方日志目錄,實現雙方解耦。
可觀測性數據分析
指標分析處理
指標采集端(如Prometheus、Grafana Agent)將從指標采集組件中采集到的指標,首先根據不同指標的特征在內存中進行聚類,對于內存中存儲時長超過兩個小時的指標數據,進行壓縮并存儲在磁盤中,以實現長久存儲指標數據的目的(使用Thanos)。采用定時觸發器的方法(Prometheus record rule),定期從時序數據庫中讀取指標數據,對其進行聚合分析,然后生成聚合指標,以支持高層抽象粒度分析。此外,由于指標監測數據隨時間價值降低,但存儲成本隨時間增加,將歷史數據進行壓縮降采樣(Thanos downsampling),在保留更長歷史數據的同時減少存儲成本,而且還可以提升查詢效率。
鏈路/日志分析處理
鏈路服務端接收到客戶端上報的鏈路數據后,首先將鏈路數據推送到消息隊列(如Kafka)中,使用消息隊列的高性能流式處理特性,為鏈路數據的后續分析、存儲提供性能保障。之后,一方面鏈路存儲應用讀取消息隊列中的鏈路數據,將其直接存儲在全文檢索中間件(如ElasticSearch)中,另一方面鏈路分析應用讀取消息隊列中的鏈路數據,在內存中進行鏈路數據的聚類分析,以構建系統服務拓撲,服務拓撲信息包含系統中組成分布式鏈路的所有應用、應用間調用的計數與平均延時、應用內部的錯誤分布,鏈路分析應用將分析后的數據也存儲在全文檢索中間件中。使用全文檢索中間件存儲鏈路數據與服務拓撲數據,可支持實現后續豐富的數據檢索場景。
日志服務端與鏈路服務端類似,日志服務端(如ElasticSearch、Loki)接收到日志采集組件上報的日志數據后,由日志解析組件基于預先定義的日志解析規則,對日志數據進行格式解析與數據過濾,并將解析后的數據構建成標準JSON數據格式,分類存儲在全文檢索中間件(如ElasticSearch)中。日志解析組件為集群部署,通過并行的流式處理,保證解析過程的高性能。日志解析規則支持多種日志解析格式,如JSON、Logfmt等,以及支持自定義日志解析器,讓運維人員可以自定義日志格式,以滿足不同業務場景的需求。
可觀測性數據價值輸出
可觀測性價值輸出示例——指標大盤
通過統一的可觀測性平臺,提供一體化、可配置化、可視化的監控、告警、排障、日志檢索等能力,實現可觀測體系的價值輸出,包括故障告警、監控大屏、鏈路檢索、日志檢索等功能。故障告警,提供針對系統故障的自動化實時告警功能。該功能支持用戶自定義基于指標、日志關鍵詞的告警規則,自動觸發告警,并通過多渠道(郵件、通信軟件)實時發送告警通知,保證運維人員能第一時間發現系統中的異常情況。監控大屏,提供針對系統當前運行狀態的監控圖表展示功能。該功能支持用戶基于預設的大屏模板創建監控大屏,監控大屏實時調用指標服務端的指標數據查詢接口,生成監控面板。監控面板支持豐富的指標展示形式,如:折線圖、柱狀圖、餅圖、度量儀等,方便運維人員在開發、測試、生產階段,直觀、高效的了解系統當前情況,或進行故障分析與定位。
可觀測性價值輸出示例——排障
鏈路檢索,提供鏈路數據查詢、鏈路詳情展示、服務拓撲分析功能。該功能支持用戶基于鏈路ID或者時間范圍查詢鏈路數據。在分布式鏈路詳情頁面中,可以直觀看到請求在系統內流轉時經過的應用服務關鍵路徑,以及每個處理階段的具體耗時情況。開發、運維人員可以利用鏈路檢索功能,進行快速的故障定位,分析各個調用環節的性能與可用性,或者統計分析用戶行為數據日志檢索,提供日志數據查詢與分析功能。運維人員可以借助日志檢索功能,從分布式系統的海量日志中,快速定位到所需日志,以進行基于日志的故障原因排查或者業務數據統計。
通過可觀測性體系設計,對復雜的云原生系統不同層次的監控對象,執行可觀測性數據采集、分析、價值輸出流程,實現云原生系統的全范圍監控,支持快速洞察系統當前運行狀況;針對系統故障進行實時告警,通過多維監控工具輔助快速的故障定位與解決,保障系統可用性;該體系提供的監控能力,同樣可以應用在系統開發與測試階段,用于快速排查開發問題,輔助進行應用性能觀測,提升業務交付的效率與質量。
未來展望
可觀測性平臺
在平臺建設過程中,我們發現關于云原生系統的可觀測性體系,仍然有可以持續深耕的領域:
- 持續剖析(Continues Profilling),是一種深入分析程序復雜性和性能的動態方法,例如CPU利用率或函數調用的頻率和持續時間。通過持續剖析可以準確定位應用程序的哪些部分在哪個時刻消耗的資源最多,這為優化核心程序執行性能提供了一個可靠的方案。
- OpenTelemetry (OTEL)標準,由OpenCensus和OpenTracing項目合并形成的CNCF項目,是一個供儀表化、生成、收集和導出遙測數據(跟蹤、指標和日志)使用的供應商中立的開源可觀測性框架。提供了一組標準規范和工具集,規范可觀測性數據的數據模型、數據采集、數據處理、數據治理和數據導出。目前各個主流開源項目(包括Kubernetes、Spring Cloud)都已經開始支持或切換到OTEL,是CNCF未來主推方案,值得關注。
- eBPF (Extended Berkeley Packet Filter),是一種數據包過濾技術,從BPF(Berkeley Packet Filter)技術擴展而來。自Linux 4.14內核以來,Linux社區為eBPF加入多個新特性和優化改進,提升了eBPF在跟蹤分析、可觀測性、安全和網絡加速等場景的應用能力。eBPF在內核中實施觀測和跟蹤,可以實現無侵入性的持續剖析,并基于各種可能的來源生成可見性事件,擴展了可以實現的可見性深度。
擴展到系統層面的全棧全鏈路觀測能力——采集
擴展到系統層面的全棧全鏈路觀測能力——透視
未來,基于eBPF在操作系統內核態實施可觀測性,與用戶態OpenTelemetry結合建立云原生觀測數據收集處理的標準范式,并引入持續剖析,不斷擴展可觀測性深度和廣度,將成為增強云原生環境可觀測性未來發展的趨勢。
總結
云原生架構在提升企業系統交付效率的同時,也使得系統的復雜性成倍提升,因此如何使系統具有可觀測性,系統內部狀態易于洞察變得尤其重要,系統可觀測性平臺正是云原生趨勢下的必然產物。本文闡述了云原生系統可觀測性平臺的從數據采集、分析、存儲、價值輸出的關鍵技術方案與數據間的關聯關系,以及如何利用可觀測性平臺高效進行故障定位與解決,降低故障定位與解決的運維成本,在最大程度上保障云原生系統的高性能與高可用性。同時,隨著操作系統eBPF、Opentelementry、人工智能機器學習等技術的不斷發展,可觀測性技術一定會在信創和云原生場景中發揮更大作用,推動下一代監控技術的發展。