行業 SaaS 微服務穩定性保障實戰

阿里云云棲號 發佈 2022-08-04T06:09:11.162426+00:00

2017 年,推特工程師 Cindy 發表了一篇名為《Monitoring and Observability》的文章,首次將可觀測性這一詞彙帶入開發者視野,通過半開玩笑的方式調侃了關於可觀測性和監控的區別。

很多研發人員在日常工作中經常回遇到以下兩個問題:竟然不可以運行,為什麼?竟然可以運行,為什麼?

因此,他們非常期望可觀測能夠提供解決問題的思路。

引言

2017 年,推特工程師 Cindy 發表了一篇名為《Monitoring and Observability》的文章,首次將可觀測性這一詞彙帶入開發者視野,通過半開玩笑的方式調侃了關於可觀測性和監控的區別。在軟體產品和服務領域,監控能夠告知我們服務究竟是否能正常運行,而可觀測性可以告訴我們為為什麼服務沒有正常運行。

從谷歌趨勢圖中可以看到,可觀測性的普及率呈現逐年上升的態勢,它也被視為系統的屬性,將逐步成為系統在做開發設計過程中就需要具備的特性。

可觀測發展趨勢

2020 年後,可觀測的搜索趨勢出現井噴,很大一部分原因是 SRE 站點可靠性工程逐步普及,國內大廠紛紛設立相關崗位和對應招聘指標,使得可觀測性在國內也得到了較多關注。這也意味著越來越多的基礎服務面臨了穩定性挑戰,而破解穩定性挑戰的重要手段就在於提供可觀測性。

上圖左下角為可觀測性的全球搜索趨勢,其中中國的搜索熱度頗高。

可觀測性定義

可觀測性是由匈牙利工程師提出的一個數學概念,指系統可以由外部輸出推斷其內部狀態的程度。換句話說,可觀測性應當可以從數據產出中分析出其內部的具體運轉細節。

難點與挑戰

業務蓬勃發展 穩定性訴求激增

F6 汽車科技是一家專注於汽車後市場信息化建設的網際網路平台公司,目前處於行業內頭部位置。隨著業務蓬勃發展,F6 支持的商戶數目短時間內暴增數十倍,同時也逐步開展了面向技師等 C 端場景的業務,比如 Vin 碼解析、數據查詢等,對於穩定性的要求顯著提高。

康威定律的作用

康威定律是 IT 史上對整個組織架構進行微服務拆分的指導性定律。任何組織在設計系統過程中都是組織架構的翻版,隨著業務膨脹,康威定律作用會導致設計微服務時拆分方式趨同於組織架構,業務增長會導致部門拆分,後續設計微服務時也會十分靠近組織架構。哪怕前期組織架構和微服務拆分不一致,後面微服務也會逐步妥協於組織架構。

雖然微服務和組織架構趨同使得系統溝通效率較高,但是這也帶來了很多分布式的系統問題。比如微服務之間的交互,沒有人能夠對服務有整體性、全局性的了解,研發人員最直接的期望就是在分布式系統中也能有單機系統的排查效率,這促使我們需要將系統以伺服器為中心的思路轉變為以調用鏈為中心的思路。

穩定性訴求激增

F6 最早進行業務開發時採用煙囪式的建設。單體應用比較簡單,但是它在擴展性和可維護性上存在很多問題。比如所有研發都在系統上進行,代碼衝突較多,什麼時間點能發布,發布會造成多少業務量損失等皆難以明確。因此,越來越多情況導致我們需要進行微服務拆分,而微服務拆分和調用又會導致調用鏈十分複雜繁瑣,如上圖右所示,幾乎無法人為分析出調用鏈路。

那麼,怎麼樣才能儘可能降低線上排查故障的難度?

可觀測演進

傳統監控+微應用日誌收集

  • ELKStack 獲取日誌和查詢 Elastalert 完成日誌告警

傳統的監控和微服務日誌收集一般採用 ELKStack 進行日誌收集。ELK 是三個開源項目的首字母縮寫,分別是 Elasticsearch、Logstash 和 Kibana。

我們重度依賴 ELK 進行微服務日誌的收集,與此同時,還使用了開源的基於 ES 的報警系統 ElastAlert 組件,主要功能是從 ES 中查詢出匹配規則,對相關類型數據進行報警。

上圖描述了通過日誌收集進行日常查詢的思路。比如研發人員會通過 pipeling 查詢線上日誌,ElastAlert 通過匹配規則告警獲取到 ES 日誌中發掘出來異常數據,kibana 可以進行查詢,也可以優先定位出系統中發生的異常。

架構升級+可觀測性引入

  • Grafana 看板+Zorka 支持 jvm 監控

隨著業務發展,系統對日誌的要求也逐步增加,比如團隊非常多,需要配置各種各樣的告警規則,因此我們引入了 Grafana 逐步替代 kibana 和 Zabbix 的查詢功能。可以通過 Grafana 的 ES 插件查詢對日誌進行告警,然後通過 alert 功能完成原先 ElastAlert 的排除,同時可以使用 Grafana 做出更直觀的可視化大屏進行展示。

除了日誌外,我們也期望收集到 Java 應用指標,因此又引入了 Zorka 開源組件。Zorka 和 Zabbix 可以簡單地進行結合,可以通過 Zorka 將收集到的信息上報給 Zabbix 進行展示。而 Zabbix 又可以通過 Grafana Zabbix 插件直接輸出數據,最終將整個應用大屏和看板信息都收集到 Grafana 界面。

Zorka 的工作機制類似於通過 Zabbix JAVA gateway 的方式,通過 Java Agent 自動掛載到 Java 進程中,用於統計常見應用容器和請求數指標等,初步解決了我們對於 Java 進程的觀測需求。

雲原生改造

  • K8s 的編排能力和微服務相輔相成迫切需要 trace 組件的支持

隨著微服務程度不斷提升,傳統方式的運維成本越來越高,因此,我們啟動了雲原生化改造。

首先,雲原生化的改造是 K8s 側就緒探針和存活探針的編寫。存活探針的編寫提升了服務的自愈能力,出現了 OOM 後服務能夠自動恢復、啟動新節點,保證數據服務正常提供。除了 K8s 外,我們還引入了 Prometheus 和 ARMS 應用監控。

Prometheus 作為 CNCF 僅次於 K8s 的 2 號項目,在整個 metrics 領域形成了足夠的話語權;ARMS 應用監控作為阿里雲商業 APM 的拳頭產品,使我們能夠結合雲原生的方式,實現研發無感,無需進行任何代碼改動即可擁有 trace 功能。更重要的是,阿里雲團隊能夠保持持續疊代,支持越來越多中間件,因此我們認為它必定會成為診斷利器。

  • JmxExporter 快速支持雲原生 Java 組件的 jvm 信息展示

進行雲原生化改造後,監控模型也發生了改變。最早的監控模型是 push,Zorka 每次發布都在同一台機器上,因此它有固定的 host;而上雲後,容器化改造導致 Pod 不再固定,且可能會出現新的應用擴縮容等問題。因此,我們將監控模型逐步從 push 轉換成 pull 模式,也更加契合 Prometheus 的收集模型,並逐步將 Zorka 從可觀測體系中剝離。

沒有使用 ARMS 直接收集 JMX 指標是因為 ARMS 不會覆蓋線上和線下所有 java 應用,沒有被覆蓋的應用也期望有 JVM 數據收集功能,而 ARMS 成本略高。因此,出於成本的考慮,我們沒有將 ARMS 作為完整接入,而是選擇了 JMX Exporter 組件。

JMX Export 也是 Prometheus 官方社區提供的 exporter 之一。它通過 Java Agent 利用 Java JMX 機制讀取 JVM 信息,可以將數據直接轉化成為 Prometheus 可以辨識的 metrics 格式,使 Prometheus 能夠對其進行監控和採集,並通過 Prometheus Operator 註冊對應的 Service Moninor 完成指標收集。

  • 利用配置中心完成應用到 owner 的精準告警

隨著公司業務蓬勃發展,人員激增,微服務暴增,研發人數和告警也劇烈增長。為了提升告警觸達率和響應率,我們重新使用了 Apollo 配置中心的多語言 SDK,通過 Go 自研了一套基於 Apollo 業務的應用提醒,整體流程如下:

通過 Grafana 收集到 ES 告警或其他場景下的告警,再通過 metrics 應用關聯到 alert ,告警時會轉發到前文提到的 Go 語言編寫的精準告警服務上。精準告警服務解析到對應應用,根據應用從 Apollo 配置中心中獲取到 owner 姓名、手機號等信息,再基於此信息通過釘釘進行告警,極大提升了消息閱讀率。

  • ARMS:無侵入支持 Trace

此外,我們還引入了阿里雲的應用實時監控服務 ARMS ,能夠在沒有任何代碼改造的前提下,支持絕大部分中間件和框架,比如 Kafka、MySQL、Dubbo 等。雲原生化後,僅需要在 deployment 里添加註解即可支持相關探針的加載,微服務的可維護性極為友好。同時,還提供了較為完整的 trace 視圖,可以查看線上應用節點調用日誌的整個 trace 鏈路,也提供了甘特圖的查看方式和依賴拓撲圖、上下游耗時圖等數據。

可觀測升級

  • Log Trace Metrics 理念升級

可觀測在國內微服務領域已遍地開花。因此,F6 公司也升級了可觀測思路。業界廣泛推行的可觀測性包含三大支柱,分別是日誌事件、分布式鏈路追蹤以及指標監控。任何時代都需要監控,但是它已經不再是核心需求。上圖可以看出,監控僅包含告警和應用概覽,而事實上可觀測性還需包括排錯剖析以及依賴分析。

最早的監控功能使用主體是運維人員,但運維人員大多只能處理系統服務告警。而上升到整個微服務領域,更多問題可能出現在應用之間,需要進行問題排障。比如服務出現了慢請求,有可能是因為代碼問題,也可能因為鎖或線程池不足,或連接數不夠等,以上種種問題最終表現出來的特徵是慢和服務無法響應。而如此多的可能性,需要通過可觀測性才能定位到真正根因。然而,定位根因並非真實需求,真實需求更多的是利用可觀測性分析出問題所處節點,然後通過替換對應組件、進行熔斷或限流等措施,儘可能提升整體 SLA 。

可觀測性還可以很好的剖析問題,比如線上服務慢,可以觀測其每個節點的耗時、每個請求中的耗時等。依賴分析也可以得到解決,比如服務依賴是否合理、服務依賴調用鏈路是否正常等。

隨著應用越來越多,對於可觀測性和穩定性的訴求也越來越多。因此,我們自研了一套簡單的根因分析系統,通過文本相似度算法將當前服務日誌進行歸類聚類分析。

  • 簡版根因分析上線

上圖為典型 ONS 故障,依賴服務進行服務升級。如果這是通過日誌抓取智能分析出來的日誌,做了很長時間 SRE 後,變更也會對於線上穩定性造成很大破壞。如果能將變更等也收集到可觀測體系中,將會帶來很大好處。同理,如果能將 ONS 要升級的信息收集到可觀測體系統中,通過種種事件關聯,能夠分析出根因,對於系統穩定性和問題排查將極為有益。

  • ARMS 支持 traceId 透出 responseHeader

F6 公司和 ARMS 團隊也進行了深入合作,探索了可觀測的最佳實踐。ARMS 近期退出了一項新功能,將 traceID 直接透出到 HTTP 頭,可以在接入層日誌中將它輸出到對應日誌,通過 Kibana 進行檢索。

客戶在發生故障時,將日誌信息和 traceID 一起上報給技術支持人員,最後研發人員可通過 traceID 快速定位到問題原因、上下游鏈路,因為 traceID 在整個調用鏈路中是唯一的,非常適合作為檢索條件。

同時,ARMS 支持直接通過 MDC 透傳 traceID ,支持 Java 主流日誌框架,包括 Logback、Log4j、Log4j2 等,也可以將 traceID 作為標準 Python 輸出。

上圖展示了典型的日誌輸出場景下 ARMS 的後台配置,可以打開關聯業務日誌和 traceID ,支持各種各樣的組件,只需在日誌系統中定義 eagleeye_traceid 即可輸出 traceID。

上述方案較為簡單,研發的修改也很少,甚至可以做到免修改,且對於 Loggin 和 Trace 的關聯程度做到了較大提升,減少了數據孤島。

  • ARMS 支持運維告警平台

ARMS 為進一步降低 MTTR ,提供了很多數據,但是數據如何到達 SRE 、DevOps 或研發運維人員手裡,依然需要花費一些心思。

因此,ARMS 上線了運維告警平台,通過可視化方式完成了告警轉發、分流等事件處理,可以通過靜默功能、分組等,支持多種集成方式。目前 F6 在用的包括 Prometheus、buffalo、ARMS 以及雲監控,其中雲監控包含了包括 ONS、Redis 在內的很多數據,研發人員或 SRE 人員在釘釘群里認領對應的響應事件即可。同時還支持報表、定時提醒、事件升級等功能,便於事後復盤和改善。

上圖為線上處理問題的界面截圖。比如釘釘群里的告警會提示上一次相似告警由誰處理、告警列表以及對應事件處理流程等。同時,還提供了過濾功能,可以分割內容,通過欄位豐富或匹配更新等方式替換內容填充模板,用於精準告警,比如識別到應用名稱後,可以關聯到對應應用的 owner 或告警人員。此功能後續也將逐步替代前文用 Go 語言寫的 Apollo SDK 應用。

  • Java 生態免修改注入 agent 方式-JAVA_TOOL_OPTIONS

同時,我們也借鑑了 ARMS 免修改注入 Agent 的方式。ARMS 通過one point initContainer 的方式注入了很多 ARMS 信息,也掛載了一個名為 home/admin/.opt 的 mount 用於存儲日誌。正因為有 initContainer ,它才能夠實現自動升級。

在 initContainer 中,可以通過調用 ARMS 接口獲取到當前 ARMS Agent 最新版本,然後下載 Java Agent 最新版本,放到 mount 目錄下,與目錄下對應的數組 Pod 進行通信,通過共享 volume 的方式完成 Java Agent 共享。過程中最核心的點在於,通過 JAVA_TOOL_OPTIONS 實現了 Java Agent 掛載。

通過上述方式,我們模擬了一套流程,通過openkruise 組件 workspread 使用 patch 方式修改 deployment。最簡單的實踐是利用 openkruise workspread給對應的 deployment 打註解,從而使得無需由研發或 SRE 團隊進行處理,只要編寫對應 CRD 即可,CRD 過程直接注入 JAVA_TOOL_OPTIONS(見上圖右下角代碼)。其應用場景也較為豐富,可以做應用流量回放、自動化測試等。

  • Prometheus Exporter

除了 ARMS 等商業化產品外,我們也積極開源,擁抱 Prometheus 社區,接入了較多 Exporter 組件,包括 SSLExport 和 BlackBoxExporter,極大提升了整個系統的可觀測性。Exporter 可以用於黑盒探針,比如探測 HTTP 請求是否正常、HTTPS 請求是否正、DNS 是否正常、TCP 是否正常等,典型的使用場景是探測當前服務入口地址是否正常。SSL 證書異常更為常見,通過 SSLExporter 可以定期輪詢證書是否過期,進一步提升可觀測性。

  • 成本觀測

除了日常服務可觀測,我們還實踐了成本可觀測等優化項目。對於雲原生環境,可以利用 kubecost 開源組件進行成本優化,直接輸出資源使用率以及報表等,反饋給研發人員進行優化,甚至可以用來發現 CPU 和內存是否呈正常比例,儘可能實現資源合理分配。

未來暢想

基於 eBPF 的 Kuberneters 一站式可觀測性

eBPF 雲原生組件愈發進入到深水區,很多問題不再只停留於應用層面,更多地會出現在系統層面和網絡層面,需要更加底層的數據進行追蹤和排障。利用 eBPF 可以更好地回答 Google SRE 提出的比如延遲、流量、錯誤率、飽和度等黃金指標出現的問題。

比如 Redis 進行閃斷切換的過程中,可能會形成 TCP 半開連接,從而對業務產生影響;再比如 TCP 連接剛建立時,backlog 是否合理等,都可以通過數據得到相應結論。

Chaos-engineering

Chaos-engineering 混沌工程鼓勵和利用可觀測性,試圖幫助用戶先發制人地發現和克服系統弱點。2020 年 6 月,CNCF 針對可觀測性提出了特別興趣小組。除了三大支柱外,CNCF 還提出了混沌工程和持續優化。

對於混沌工程是否能劃分在可觀測性里,當前社區依然存在疑議,而 CNCF 的可觀測性特別興趣小組裡已包含了 chaos-engineering 和持續優化。我們認為,CNCF 的做法有一定道理,混沌工程可以被認為是一種可觀測性的分析工具,但其重要前提是可觀測性。試想,如果在實施混沌工程過程中發生故障,我們甚至都無法確定它是否由混沌工程引起,這也將帶來極大麻煩。

因此,可以利用可觀測性儘可能縮小爆炸半徑、定位問題,通過 chaos-engineering 持續優化系統,提前發現系統薄弱點,更好地為系統穩定性保駕護航。

OpenTelemetry

OpenTelemetry 是一個通過多個項目合併而來的開源框架。我們需要更加面向終端研發統一的可觀測性視圖,比如期望將 logging、metrics 和 tracing 數據進行互相關聯打標,儘可能減少數據孤島,通過多數據源的關聯提升整體可觀測性。並利用可觀測性儘可能縮短線上故障排查時間,為業務服務恢復爭取時間。

原文連結:https://click.aliyun.com/m/1000351555/

本文為阿里雲原創內容,未經允許不得轉載。

關鍵字: