Dubbo 可觀測性實踐之 Metrics 功能解析

語言: CN / TW / HK

在 2018 年,Observability(即可觀測性)首次被引入 IT 領域,並逐漸取代只關注系統整體可用性的傳統監控。隨著雲原生技術的不斷髮展,企業從單體架構發展到分散式架構,使用容器部署拆分出來的一眾微服務、與業務聯絡緊密,傳統的監控僅適合報告系統的整體執行情況無法進行高度細化的分析與關聯,於是需要將研發視角融入監控,發展具有比原有監控更廣泛、更主動、更細粒度的能力,這種能力就是可觀測性。

Dubbo 3 的建設規劃有上雲,可觀測性是上雲必不可少的能力,叢集間根據例項可用性負載均衡、Kubernetes 彈性伸縮、建立例項健康模型等等運用場景都需要可觀測性。

目前 Dubbo 3 的可觀測性正在建設中,本文主要介紹 Metrics 模組基礎知識與進度。

零-APM 介紹

Cloud Native

APM全稱是 application performance management,翻譯過來就是應用的效能管理,主要是用來管理和監控軟體系統的效能和可用性。 可以保障線上服務的質量,是一個重要的服務治理工具。

如果從系統職能上分的話,APM 系統的話可以可以分為三個子系統,分別是 Metrics、Tracing 和 Logging。

Metrics 也叫指標監控,主要是負責處理一些結構化的可以聚合的一些指標資料。

Tracing 又叫鏈路追蹤,主要是圍繞單次請求進行資訊處理,然後所有的資料都被繫結到系統的單個請求或者說單個事務上。

Logging 是日誌監控,主要梳理一些非結構化的事件。

Metrics 結構與型別

Cloud Native

一個 Metrics 由四部分組成,第一個是指標名稱;第二個是 labels 或者說 tags 也就是標籤,是一些維度資料,這些維度資料可以用來做一些過濾或者聚合查詢;第三個是時間戳,就是它的時間欄位;第四個就是具體的指標的一個值。

除了上述四個部分之外,還有一個非常重要的欄位沒有體現在資料模型裡,就是這條資料的指標型別。不同的指標型別的話它是會用在不同的監控場景,同時它的一些查詢和視覺化的一些方式,也會有一些區別。

下面簡單介紹一些常用的指標型別。

第一個是 Gague,這個型別的特點就是他是可增可減的。比如說 CPU 負載、活躍執行緒數、記憶體使用率、磁碟使用率,這些數它都是會隨著時間進行波動的。它儲存和展示的都是一個瞬時值。

第二個指標型別 Counter,這個型別的特點是隻增不減,比如說介面請求總量,對於這個型別,一般會有幾個衍生的處理,一個是可以比較兩個時間點前後的一個差值,這樣可以計算出這個單位時間內的請求的一個波動量。第二個就是對時間進行求導之後,就得到 QPS 這種型別的一個欄位。

第三個指標型別是 Summary,主要做的是一個彙總統計,比如說平均值,分位數這樣的一些指標。然後這個指標型別的話主要用於介面響應延遲這樣的一個場景。因為我們平時在看介面響應延遲這個指標的時候,一般除了看它的平均值,可能還會看一些那種分位數指標。

第四個指標型別是 Historgram,它是一個柱狀統計,一般是會先對指標進行一個分桶,分桶之後再去統計它的一些值。比如說我們的還是以那個介面響應延遲為例的話,它會比如說有一些那種視覺化展示的話,展示它的那個柱狀圖。

指標收集

Cloud Native

Dubbo 的指標體系,總共涉及三個模組,分別是指標收集、本地聚合、指標推送。

  • 指標收集:將 Dubbo 內部需要監控的指標推送至統一的 collector 中進行儲存。

  • 本地聚合:指標收集獲取的均為基礎指標,而一些分位數指標則需通過本地聚合計算得出。

  • 指標推送:而獲取指標的話有兩種方式,第一種是直接訪問 Dubbo 暴露的介面就可以獲得 Dubbo 內部統計的指標,第二種是接入第三方伺服器進行指標推送,Dubbo 會將收集和聚合後的指標通過 pull 或者push的方式推送至第三方伺服器,目前只涉及 Prometheus,其中 pull 或者 push 由使用者選擇。

指標收集

指標收集的目的是為了儲存微服務的執行狀態,相當於給微服務拍了一個快照,以及為進一步的分析(比如指標聚合)提供基礎資料。

上圖為 Dubbo 的架構圖,本方案中指標收集的埋點位置或者說切入位置是在 provider 中通過 SPI 的方式新增一個 Filter。

這裡貼了部分程式碼,展示了其中一部分指標收集的邏輯。

我們是通過 interfaceName、methodName、group、version 四個維度的資訊作為 map 儲存結構的 key ,當然這四個維度的資訊最後在指標匯出的時候都會轉換成前面 metrics 儲存結構的 labels 或者說 tags。

接下來給大家展示一個的是我們一個預設儲存器的成員變數。

運用分段鎖結構的 ConcurrentHashMap 來保證併發度,其中的 MethodMetric 就是前文說的四個維度資訊組成的一個 class。

有一個比較重要的結構是一個 MetricsListener 的 list ,這裡其實是一種生產者消費者的模式,因為預設收集器是我們預設接入的,但是如果需要收集其他指標則需要繼續在此新增監聽,讓其他收集器監聽預設收集器的狀態,當預設收集器收集到了值就向監聽列表推送一個事件,這樣其他收集器就能收集到元資訊再進一步加工處理。這裡也是本地聚合實現的一個邏輯,具體細節不展示了,有興趣的同學可以去看看 Dubbo 3.1 的程式碼。

本地聚合-滑動視窗與 TDigest

本地聚合主要使用滑動視窗與 TDigest,滑動視窗原理如圖,假設我們初始有 6 個 bucket,每個視窗時間(即一個 bucket 在 current 指標下的停留時間)設定為2分鐘,每次寫入指標資料時,會將資料分別寫入 6 個 bucket 內,也就是一條資料寫六遍,我們會每隔兩分鐘移動一個 bucket 並且清除原來 bucket 內的資料,讀取指標時,會讀取當前 current 指向的 bucket 內的指標資料,以達到滑動視窗的效果。

滑動視窗的作用是為了能夠對近期的資料做一個聚合,使得我們每次指向的 bucket 裡面儲存的都是從當前時間到過去一個 bucket 生命週期(即 [ now - bucketLiveTime * bucketNum, now ] 這樣一個時間區間)的指標資料。其中 bucket 的生命週期受視窗時間和 bucket 數量控制,這個支援使用者自定義配置。

接下來是介紹 Dubbo 分位數指標的處理,我們常說的 p99,p95 這樣的指標就是分位數指標,p99 是指在 100 個請求裡面,響應時延排名第 99 位的值,可以較好的反應一個服務的可用性,被稱為黃金指標。

Dubbo 在計算分位數指標的時候使用了 TDigest 演算法,TDigest 是一個簡單,快速,精確度高,可並行化的近似百分位演算法。

TDigest 使用的思想是近似演算法常用的 Sketch,也就是素描,用一部分資料來刻畫整體資料集的特徵,就像我們日常的素描畫一樣,雖然和實物有差距,但是卻看著和實物很像,能夠展現實物的特徵。

下面是 TDigest 的原理。假如有 500 個 -30 ~ 30 間的數字,可以使用概率密度函式也就是 PDF 函式表示這一資料集

該函式上的某一點的 y 值就是其 x 值在整體資料集中的出現概率,整個函式的面積相加就正好為 1 ,可以說它刻畫了資料在資料集中的分佈態勢,也就是大家熟悉的正態分佈。

有了資料集對應的 PDF 函式,資料集的百分位數也能用 PDF 函式的面積表示。如下圖所示,百分位數 P75 就是面積佔了 75% 時對應的 x 座標。

PDF 函式曲線中的點都對應著資料集中的資料,當資料量較少時,我們可以使用資料集的所有點來計算該函式,但是當資料量較大時,只有通過少量資料來代替資料集的所有資料。

這裡,需要將資料集進行分組,相鄰的資料分為一組,用平均數和來代替這一組數。這兩個數合稱為質心數,然後用這個質心數來計算 PDF,這就是 TDigest 演算法的核心思想。

如下圖所示,質心數的平均值作為x值,個數作為 y 值,可以通過這組質心數大致繪製出這個資料集的 PDF 函式:

對應的,計算百分位數也只需要從這些質心數中找到對應的位置的質心數,它的平均值就是百分位數值。

很明顯,質心數的個數值越大,表達它代表的資料越多,丟失的資訊越大,也就越不精準。如這張圖所示,太大的質心數丟失精準度太多,太小的質心數則有消耗記憶體等資源較大,達不到近似演算法實時性高的效果。

所以,TDigest 在壓縮比率的基礎上,按照百分位數來控制各個質心數代表的資料的多少,在兩側的質心數較小,精準度更高,而在中間的質心數則較大,以此達到 P1 或 P99 的值要比 P20 更準確的效果。

指標推送之 Prometheus

指標推送的作用是為了將目前 Dubbo 提供的指標進行進一步的儲存、運算和視覺化,目前第三方伺服器只支援 Prometheus。 Prometheus 是 CNCF 開源的一個應用於應用監控的系統。 主要有三個模組組成,分別是獲取資料,儲存資料,資料查詢。

獲取資料有 Pull 和 Push 兩種方式,也是 Dubbo 接入的方式;儲存資料 Prometheus 是用的時序資料庫這裡就不展開講了;資料查詢是其自定義的一套查詢 IDL,可以接入 Grafana 這一類報警系統,當監控指標異常時候可以使用郵件報警或者電話報警。

目前的設計:

指標推送只有使用者在設定了<dubbo:metrics />配置且配置 protocol 引數後才開啟,若只開啟指標聚合,則預設不推送指標。

  • Promehteus Pull ServiceDiscovery:啟動時根據配置將本機 IP、Port、MetricsURL 推送地址資訊至中間層,暴露 HTTP ServiceDiscovery 供 Prometheus 讀取,配置方式如 <dubbo:metrics protocol="prometheus" mode="pull" address="${dubbo-admin.address}" port="20888" url="/metrics"/>,其中在 Pull 模式下 address 為可選引數,若不填則需使用者手動在 Prometheus 配置檔案中配置地址。

  • Prometheus Push Pushgateway:使用者直接在 Dubbo 配置檔案中配置 Prometheus Pushgateway 的地址即可

<dubbo:metrics protocol="prometheus" mode="push" address="${prometheus.pushgateway-url}" interval="5" />

其中 interval 代表推送間隔

相關 Dubbo Metrics 功能我們預計會在 3.1.2 / 3.1.3 版本中正式 release 釋出。

服務治理與商業化

Cloud Native

Dubbo 3 的可觀測性建設是 Dubbo 3 上雲必不可少的一個環節。 在 Dubbo 3 對標的商業化產品微服務引擎 MSE 中,針對 Dubbo 3 做了全方面的增強,以一種無侵入的方式增強 Dubbo 3 服務,使其具備完整的微服務治理能力。

在建設 Dubbo 可觀測性的同時,我們也在結合 OpenSergo 標準構建 Dubbo 3 的完整的服務治理體系。

OpenSergo 在聯合各個社群進行進一步的合作,希望通過社群來一起討論與定義統一的服務治理標準。當前社群也在聯合 bilibili、CloudWeGo 等企業、社群一起共建標準,也歡迎感興趣的開發者、社群與企業一起加入到 OpenSergo 服務治理標準共建中。歡迎大家加入 OpenSergo 社群交流群(釘釘群)進行討論:34826335