<SOFA:Channel/>,有趣實用的分佈式架構頻道。
本文根據 SOFAChannel#6 直播分享整理,主題:輕量級監控分析系統 SOFALookout 原理講解和功能演示。
回顧視頻以及 PPT 查看地址見文末。
歡迎加入直播互動釘釘羣: 23195297,不錯過每場直播。
你們好,我是響風,來自螞蟻金服, 如今是 SOFALookout 的開源負責人。本期 SOFAChannel 我給你們帶來主題是《輕量級監控分析系統 SOFALookout 原理講解和功能演示》的分享。本期的講解內容以下將從如下四個部分展開:前端
歡迎你們 Star 我,SOFALookout:github.com/sofastack/s…node
如今咱們開始第一部分,先介紹一些基本概念。6 月初,SOFALookout 服務端開源,具體內容能夠查看相關文章:螞蟻金服輕量級監控分析系統 SOFALookout 服務端開源,SOFALookout 客戶端在以前也已經開源。目前整個系統是真正地能夠玩轉起來的,這裏先介紹一下 SOFALookout。ios
SOFALookout 是螞蟻金服開源的一款解決系統的度量和監控問題的輕量級中間件服務。開源版本只提供對 Metrics 的處理部分:涵蓋 Metrics 數據的產生,也就是 Metrics 的埋點、收集、加工、存儲與查詢等一系列服務。git
介紹一些 Metrics 的前置知識:github
第一是時序數據,比較正式的解釋是「基於穩定頻率持續產生的一系列指標監測數據」。簡單說橫軸是時間,縱軸是數值的狀況下,第一印象能夠作成走勢圖的數據一般就是時序數據。好比 2009 年到 2018 年每一年雙十一天貓的成交額,就構成了時序數據。spring
第二是標籤(Tag),它用於代表指標項監測針對的具體對象。仍是以剛纔的成交額爲例子,其實咱們要監測的指標是「成交額」,可是「成交額」並無標明要監測的對象,即誰的成交額,哪一個省的成交額,也就是缺乏「定語」。標籤的做用就至關因而「定語」。好比「天貓的 浙江省的 成交額」,在代碼中一般會有鍵值對來描述,好比 type="天貓",province="浙江"。docker
第三是時序數據庫,即專門爲存查時序數據而設計的數據管理系統。主要有如下幾個特色:數據庫
如下是一些常見的開源時序數據庫,因爲篇幅關係,就不一一介紹了。編程
下面再來看一下傳統 Metrics 和 Metrics 2.0 的對比。性能優化
傳統 Metrics 是我對它的稱呼,簡單來講它只有 Name 和 Value,沒有顯式的 Tags 概念。好比 "temperature = 29",溫度=29,固然這裏都省略了時間戳。這個表達式並無指出監測對象,傳統 Metrics 的作法是,將監測對象的信息編碼到 Name 裏,所以可能就變成了 "temperature.hangzhou=29"。這裏是有一些隱式的 Tags 信息的,只是被編碼到 Name 裏了。
這種作法很快會致使一個問題,咱們來看下一個例子: shanghai.host1.foo.exporter.bar
。 只看這個名字的話幾乎很難知道這個 Metrics 統計的是什麼。這是由於它並無把字段對應的 Key 編碼到名字裏,因此在缺乏一些上下文的狀況下,咱們很難讀懂它的含義。
另外,字段的順序也是很重要的,不能寫錯,這是由於編碼到 Name 裏的只有 Tag 的 Value,Key 不在裏面,因而又有了另一種編碼方式:zone.shanghai.host.host1.app.foo.counters.exporter.bar
。這種方式將 Tag 的 Key 也編碼在Name 裏。但帶來的問題也很明顯:Name 愈來愈長。
咱們再看下一個例子: login.success.h5
,它想表達來自 H5 平臺登陸成功的次數。假設咱們還有其餘平臺,好比安卓、IOS,咱們想求全部平臺的總登陸成功次數,那麼就須要作一個聚合操做。一般時序數據庫會提供型號來匹配全部值。
其實上面這些都是舊版本 Graphite
的例子, 不過它在 2017 年末的版本支持了 Tags 概念,因此已經不能拿新版來當反面教材了。
這是 Dropwizard 客戶端的一個簡單 Demo,它是一個很流行的 Metrics 埋點客戶端,可是隻能支持傳統 Metrics 的概念。
MetricRegistry registry = new MetricRegistry();
Counter h5Counter = registry.counter("login.success.h5");
h5Counter.inc();複製代碼
咱們再來看 Metrics 2.0,其實 Metrics 2.0 也就只是多了 Tags 的概念,這裏一樣省略了 Timestamp。
這是 OpenTSDB 風格的數據描述。
{ "metric": "login.counter",
"tags": {
"result": "success",
"platform": "h5"
},
"timestamp": 1560597254000,
"value": 100
}複製代碼
這是 Prometheus 的描述方式。
temperature{city="hangzhou"}=29複製代碼
這是對應的 lookout-client 的埋點代碼。
Registry registry = …;
Id loginCounter = registry.createId("login.counter");
Id id = loginCounter.withTags(
"result", "success",
"platform", "ios"
);
registry.counter(reqId).increment();複製代碼
能夠看到它們都顯式支持了 Metrics 2.0 的概念。
這裏咱們花了點時間強調傳統 Metrics 與 Metrics 2.0版本的區別,主要是想強調合理使用 Name 和 Tags,避免將 Tags 都編碼在 Name 裏的傳統作法。如今基本上流行的開源時序數據庫都經過本身的方式支持了Metrics 2.0 的概念。
介紹完前置知識以後,咱們開始第二部分:SOFALookout 的客戶端使用。
lookout-client 是 JVM 平臺上的 Metrics 埋點客戶端。下圖是 lookout-client 的包結構:
API 包包含接口模型和空實現。API 包列出了一些重要的類,前 4 個是常見的 Metrics 數據模型。Registry 用於直接管理 Metrics,是 Metrics 的容器。Observer 負責觀察 Registry,好比按期將 Registry 的整個快照數據導出到控制檯或者是存儲層,僅依賴 API 包就能夠編程。此時用的是空實現,須要引入實現包,這樣才能真正導出數據。最後,擴展包裏則包含收集常見指標的實現, 好比 CPU 內存信息。
接下來我將演示 SOFALookout 客戶端的使用。我會使用開源的 lookout-client,介紹 SOFALookout 裏幾個基本概念和它們的使用,在整個過程當中還會討論 Tags 的合理使用。
SOFALookout 客戶端的相關演示操做能夠在文末獲取 Demo 地址以及演示視頻查看地址。
第三部分是 SOFALookout 的服務端使用。整個服務端有 2 個應用:Gateway(多協議的數據收集與處理設計與實實現)和 Server(PromQL 與多種存儲層的設計與實現)。各個客戶端將數據上報到 Gateway,Gateway 進行處理,而後落庫。Server 則負責對外提供查詢服務。
咱們來仔細看一下 Gateway 的設計與實現,下圖代表了數據的流動方向:
Gateway 負責收集數據,適配了多種協議。一般只要是支持 Metrics2.0 概念的協議均可以進行適配。這部分是由 Importer 負責的,目前主要是客戶端主動上報數據爲主。若是是像普羅米修斯的拉模式的話,則須要和服務發現系統或部署平臺打通,這個目前暫時沒有支持。
Gateway 還會負責數據的基本清洗,好比過濾掉一些已知的壞數據。這裏使用的是管道過濾器模式, 因此咱們能夠很容易加入一個新的切面邏輯.
通過各類過濾器以後, 數據到達了 exporter 適配器,它負責將數據寫入多種存儲。
下面是 Server 的設計與實現,下圖代表了數據的流動方向:
Server 提供了與普羅米修斯一致的 HTTP API,它負責分析收到的 PromQL 語句,而後執行,在取數據的地方適配底層存儲。
因爲 Server 是計算與存儲分離的架構,所以須要注意將一些聚合計算下推到存儲層,而不是將原始數據取到內存裏再進行計算,不然會很慢。
這裏我提一下爲何咱們選擇適配普羅米修斯的 API,而不是其餘時序數據庫的 API:其中一個重要緣由是它的查詢能力明顯比其餘時序數據庫的查詢能力強大,也比較簡潔,特別是在跨多個 Metrics 查詢時。
舉一個例子,假設咱們有一個 Metrics 記錄了成功數,有另外一個 Metrics 記錄了總數,想求成功率。顯然就是兩個Metrics 除一下就好了,好比下方的代碼,就是表達了這個意思:
sum(success{zone="..."}) by(service{zone="..."}) / sum(total{zone="..."}) by(service)複製代碼
InfluxDB 的話,其實也能夠作到,但前提是它須要將成功數和總數放在同一個 measurement 下,所以並不能對任意兩個指標作四則運算。
OpenTSDB 的聚合查詢能力則明顯比較弱了,但好在它能支持同時查多個查詢,實在沒法處理的狀況下能夠取回來而後本身作計算。可是這個步驟前端的 grafana 並不能幫咱們作掉。
固然 PromQL 的強大,這只是其中一方面,並不表明它就全面優與其餘的 QL。
下面,我來演示一下 SOFALookout 服務端的部署流程,以及演示整套系統從數據收集到展現的玩法。
爲了演示流暢, 使用 Docker 來部署軟件,我已經事先將要用到鏡像拉到本地了。
預先拉取鏡像:
docker image pull grafana/grafana && \
docker image pull elasticsearch:5.6 && \
docker image pull docker.io/xzchaoo/lookout-allinone:1.6.0-SNAPSHOT複製代碼
再啓動存儲層, 這裏用的是 ES:
docker run -d --name es -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:5.6複製代碼
執行 docker logs -f es
查看 es 的啓動狀況。
啓動 SOFALookout,由於演示機是 mac, Docker 的 host 網絡模式沒法正常工做,而 SOFALookout 默認鏈接到 localhost 的 es,這會致使錯誤,所以須要覆蓋參數。
咱們須要建立一個配置文件, 好比 foo.properties,有以下內容:
gateway.metrics.exporter.es.host=es
metrics-server.spring.data.jest.uri=http://es:9200複製代碼
而後啓動SOFALookout容器, 將該配置文件掛到指定路徑, 而且使用 Docker 的 link 參數來引用 es 容器的地址:
docker run -it \
--name allinone \
--link es:es \
-e TZ='Asia/Shanghai' \
-p 7200:7200 \
-p 9090:9090 \
-v $PWD/foo.properties:/home/admin/deploy/foo.properties \
-e JAVA_OPTS="-Duser.timezone=Asia/Shanghai -Dlookoutall.config-file=/home/admin/deploy/foo.properties" \
docker.io/xzchaoo/lookout-allinone:1.6.0-SNAPSHOT複製代碼
最後啓動 grafana,一樣使用了 link 參數:
docker run --name grafana -d -p 3000:3000 --link allinone:allinone grafana/grafana複製代碼
SOFALookout 啓動以後能夠訪問其 9090 端口,咱們打開 http://localhost:9090,有一個簡單的控制檯, 咱們搜索一個 Metrics: jvm.classes.loaded{app="*"}
,這是 lookout-client 擴展包自動採集的數據。執行以前寫的 lookut-client demo 程序,此時應該有幾個點的數據了,須要等一段時間數據點纔會更多,這段時間內咱們能夠先到 grafana 上探索一下。
最後是 SOFALookout 的發展規劃:
近期,對於 SOFALookout 開源版本主要是以完善適配爲主,包括計算下推到 E,和適配其餘時序數據庫。以後,咱們也會開源關於 Trace 數據的處理模塊。
以上內容由 SOFAChannel#6 直播分享整理,若是你們有疑問能夠在釘釘羣(搜索羣號便可加入:23195297)或者 Github 上與咱們討論交流,咱們將進行解答。也歡迎你們一塊兒參與共建呀~
SOFALookout:github.com/sofastack/s…
公衆號:金融級分佈式架構(Antfin_SOFA)