基于Prometheus和Grafana打造业务监控看板
前言
業(yè)務(wù)監(jiān)控對許許多多的場景都是十分有意義,業(yè)務(wù)監(jiān)控看板可以讓我們比較直觀的看到當前業(yè)務(wù)的實時情況,然后運營人員可以根據(jù)這些情況及時對業(yè)務(wù)進行調(diào)整操作,避免業(yè)務(wù)出現(xiàn)大問題。
老黃曾經(jīng)遇到過一次比較尷尬的“事故”。
其中一條業(yè)務(wù)線,服務(wù)著的其中一個商家,把大部分流量切到另外一個地方去了,而我們的運營人員在當天卻是完全不知情,第二天看了昨天的統(tǒng)計報表之后才發(fā)現(xiàn)這個商家的量少了很多,才能跟進協(xié)調(diào)處理。
ps: 當時實時報表比較欠缺,都是第二天凌晨生成昨天的數(shù)據(jù)報表,也沒有告警機制。
后面就弄了個大屏幕做了業(yè)務(wù)監(jiān)控的實時看板,看一眼就知道有什么風(fēng)吹草動了。
先來看一下最終的效果圖。
這個圖里面主要包含了下面幾個內(nèi)容。
總的訂單數(shù)量
退單的數(shù)量
創(chuàng)建訂單的頻率
不同渠道的訂單量
不同渠道的退單量
下面就介紹一下如何實現(xiàn)這樣的業(yè)務(wù)監(jiān)控。
搭建基礎(chǔ)設(shè)施
這里涉及的基礎(chǔ)設(shè)施就有兩個,一個是prometheus,另一個是grafana。
先啟動prometheus,這里直接用docker啟動。
$base = Split-Path -Parent $MyInvocation.MyCommand.Definition $prometheusyml = Join-Path $base prometheus.yml $fileconfig = Join-Path $base "config"write-host $prometheusyml write-host $fileconfigdocker run `--name prom `-p 9090:9090 `-v ${prometheusyml}:/etc/prometheus/prometheus.yml `-v ${fileconfig}:/etc/prometheus/fileconfig `prom/prometheus:v2.20.1下面是prometheus.yml
global:scrape_interval:?????15s?evaluation_interval:?15salerting:alertmanagers:-?static_configs:-?targets:#?-?alertmanager:9093rule_files:scrape_configs:-?job_name:?'file_ds'file_sd_configs:-?refresh_interval:?10sfiles:-?./fileconfig/*.yml這里用了基于文件的發(fā)現(xiàn)機制,沒有用靜態(tài)的。更多其他方式,參見 ?https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config
這個時候prometheus已經(jīng)是運行起來了。
再來就是grafana了,啟動這個更加簡單。
docker run -d --name grafana -p 3000:3000 grafana/grafana:7.1.3執(zhí)行完,訪問 localhost:3000 就可以看到登錄界面了。
確定業(yè)務(wù)指標(metrics)
確定指標可以說是整個業(yè)務(wù)監(jiān)控中最最最最最為主要的一個環(huán)節(jié)了,只有明確了我們要監(jiān)控什么,我們才可以在業(yè)務(wù)上去進行埋點,拿到想要的數(shù)據(jù)。
這個其實和我們平時面對的需求是一個樣的,需求明確了,做出來的東西才可能是我們想要的,需求不明確,做出來的東西可能就不會是我們想要的了。
為了幫助大家簡單的理解相關(guān)的內(nèi)容,這里舉個監(jiān)控的例子,監(jiān)控不同渠道的下單和退單量。
涉及到量的,在一天內(nèi)基本上是屬于只增不減的,這個時候我們一般會選用 counter 類型來處理。
一個是下單,一個是退單,所以這里定義兩個
yyyorder_created_total
yyyorder_canceled_total
counter類型的,一般在命名的時候最好都用_total作為結(jié)尾。
還有不同渠道呢?
渠道我們就用 lable 來標識一下。
最后展現(xiàn)格式大致如下:
yyyorder_created_total{appkey="mt",opreator="cw"}?1 yyyorder_canceled_total{appkey="pdd",opreator="cw"}?2這里也要注意一個問題,確定指標的時候,也要避免定義太多指標出來,如果可以,考慮用label去進行區(qū)分同性質(zhì)的內(nèi)容。
業(yè)務(wù)埋點
在明確了業(yè)務(wù)指標之后,就要在對應(yīng)的業(yè)務(wù)上去進行埋點操作,會對業(yè)務(wù)代碼有一定的侵入性,當然如果業(yè)務(wù)代碼寫得足夠好,耦合的東西少,或許可以借助AOP來埋點,從而降低侵入性。
后面就寫個簡單的例子來模擬業(yè)務(wù)埋點這一塊。
創(chuàng)建一個ASP.NET Core的項目,并安裝prometheus-net.AspNetCore這個nuget包。
<ItemGroup><PackageReference?Include="prometheus-net.AspNetCore"?Version="3.6.0"?/> </ItemGroup>其次是啟用 ASP.NET Core exporter middleware
public?void?Configure(IApplicationBuilder?app,?IWebHostEnvironment?env) {if?(env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseRouting();app.UseAuthorization();app.UseEndpoints(endpoints?=>{//?這一句。endpoints.MapMetrics();endpoints.MapControllers();}); }最后就是埋點了。
[ApiController] [Route("")] public?class?HomeController?:?ControllerBase {private?static?readonly?Counter?OrderCreatedCount?=?Metrics.CreateCounter("yyyorder_created_total",?"Number?of?created?orders.",?new?CounterConfiguration{LabelNames=?new?[]?{?"appkey",?"opreator"?}});private?static?readonly?Counter?OrderCanceledCount?=?Metrics.CreateCounter("yyyorder_canceled_total",?"Number?of?canceled?orders.",?new?CounterConfiguration{LabelNames?=?new[]?{?"appkey",?"opreator"?}});[HttpGet]public?string?Get(){var?appKeys?=?new[]?{?"ali",?"pdd",?"mt"?};var?opreators?=?new[]?{?"cw",?"pz"?};var?rd?=?new?Random((int)DateTimeOffset.Now.ToUnixTimeMilliseconds()).Next(0,?2000);var?appKeyidx?=?rd?%?3;var?opreatoidx?=?rd?%?2;OrderCreatedCount.WithLabels(appKeys[appKeyidx],?opreators[opreatoidx]).Inc();var?cRd?=?new?Random((int)DateTimeOffset.Now.ToUnixTimeMilliseconds()).NextDouble();if?(cRd?<?0.3d){OrderCanceledCount.WithLabels(appKeys[appKeyidx],?opreators[opreatoidx]).Inc();}return?"ok";} }上面這個控制器中,創(chuàng)建了兩個Counter,就是上面確定業(yè)務(wù)指標中定義好的。
這里是每訪問一次,就創(chuàng)建一個訂單,同時生成一個隨機數(shù),如果是小于0.3,那么就當它是退單的,這樣就可以把兩種指標都模擬出來了。
程序剛啟動是有部分默認指標的。
當我們訪問埋點的地址后,可以發(fā)現(xiàn)我們自定義的業(yè)務(wù)指標也已經(jīng)有數(shù)據(jù)了。
到這里,數(shù)據(jù)已經(jīng)有了,我們要怎么呈現(xiàn)呢?
要想呈現(xiàn)數(shù)據(jù),我們需要先讓prometheus來保存我們的業(yè)務(wù)指標數(shù)據(jù)。
數(shù)據(jù)寫入
把數(shù)據(jù)寫入prometheus有兩種方式,一種是pull,一種是push。
pull是讓prometheus主動去拉取我們產(chǎn)生的數(shù)據(jù),只要我們暴露一個地址出來即可,這種也是比較推薦的做法。
push方式要借助pushgateway,埋點數(shù)據(jù)要先主動推送到pushgateway,后面在由pushgateway把數(shù)據(jù)寫進prometheus。
默認情況下,當我們用了endpoints.MapControllers();之后,就會把數(shù)據(jù)暴露在 http://ip:port/metrics 這個地址上。
知道要用pull的方式后,還要做什么呢?當然就是要去配置promethues了。
前面我們的 scrape_configs 是通過文件去自動發(fā)現(xiàn)的,所以只要在掛載的路徑上面加一個對應(yīng)的yml文件就可以了。
老黃這里加了一個nc-service.yml,具體內(nèi)容如下:
-?labels:service:?ncproject:?demotargets:?-?192.168.1.103:9874-?192.168.1.103:9875這個時候就可以在Targets里面看到我們這兩個地址的信息了。
通過prometheus的默認界面,也可以發(fā)現(xiàn)數(shù)據(jù)已經(jīng)正常讀取了。
后面就是真正的數(shù)據(jù)查詢和展示了。
數(shù)據(jù)展示
通過上面的步驟,我們已經(jīng)保證數(shù)據(jù)可以正常寫入和查詢了,現(xiàn)在就在grafana中創(chuàng)建一個業(yè)務(wù)監(jiān)控看板了。
在grafana中先配置我們的數(shù)據(jù)源。
這里填上我們prometheuse的地址保存就可以了,可以看到那個綠色的提示,告訴我們這個數(shù)據(jù)源是正常工作的了。
先來一個總的訂單數(shù)。
創(chuàng)建一個新的dashboard,再創(chuàng)建一個Panel。
我們在panel中填寫我們的信息還有就是選擇要的圖形。
然后就是寫上查詢條件,就可以看到我們要的結(jié)果了。
訂單總數(shù)這個查詢?nèi)缦?#xff1a;
sum(ceil(increase(yyyorder_created_total[1d])))里面用到了, sum、ceil、increase這三個函數(shù)。
其中 increase 是用來統(tǒng)計一段時間范圍內(nèi)的增量。后面帶了 [1d] 這個范圍表明這里是查看1天內(nèi)的增量。
ceil是用來把increase的結(jié)果進行四舍五入的,可能有人會好奇,怎么還會要四舍五入呢?
看看下面這個圖,大家就會發(fā)現(xiàn),非常多的小數(shù)點。
其實這個和prometheus的統(tǒng)計方法是有關(guān)系的,這里不展開,先這樣用著。
sum 這個是用來求和的,指標中還包含了很多l(xiāng)abel,我們還要把每個label的求和,才是真正的結(jié)果。
所以這里就得到了下面這個結(jié)果。
退單總數(shù)的查詢和訂單總數(shù)一樣,只是把名字換成退單的即可。
sum(ceil(increase(yyyorder_canceled_total[1d])))再來看看各渠道的訂單統(tǒng)計。
既然是看各渠道的統(tǒng)計,那么這里就要用到前面定義好的label了。appkey代表的就是渠道,那么我們基于它去分一下組就可以了。
就得到下面的查詢。
sum?by?(appkey)?(ceil(increase?(yyyorder_created_total[1d])))結(jié)果如下:
同理,各渠道退單的也是一樣的寫法
sum?by?(appkey)?(ceil(increase?(yyyorder_canceled_total[1d])))ps: 如果想把訂單和退單的放在一個圖里面,可以加多個查詢。
示例如下:
現(xiàn)在有了所有渠道的總量,各個渠道獨立的總量,那么我們有辦法知道某個時間段的趨勢嗎?
這個是肯定有的,且聽老黃慢慢道來。
有上面這個疑問,多半是經(jīng)歷過,某個時間段量非常多,但是有的時間段又幾乎為零,玩的就是心跳呀。
我們可以把這個稱之為時間段內(nèi)的訂單增長情況。
這里需要用到rate函數(shù),這個就是幫助我們統(tǒng)計增長速率的函數(shù)。
它統(tǒng)計的是每秒的平均增長率,這個粒度有點太細,所以我們會在這個基礎(chǔ)上乘以60,放大到一分鐘。
然后在看它sum的結(jié)果,最后才四舍五入。
ceil(sum(rate(yyyorder_created_total[5m])?*?60))結(jié)果如下:
從這個結(jié)果可以看出,訂單大部分時間都沒有增長,只在中間那個時間段,有部分單進來。
到這里主要的各個小panel已經(jīng)完成了,剩下的就是在dashboard里面調(diào)整位置,大小那些了。
總結(jié)
這樣打造出來的監(jiān)控看板還是挺不錯的,不過還是要注意下面幾個問題的
prometheus是把數(shù)據(jù)存儲在本地的,總是會達到上限的,這里要么是定期刪,要么是寫到遠程存儲。
prometheus自己獨立的查詢語法可能剛開始會比較不適應(yīng),查不出自己想要的結(jié)果,這里多查查資料,多實踐基本問題也不大。
業(yè)務(wù)埋點這一個塊,還是要盡可能的減少對現(xiàn)有業(yè)務(wù)代碼的侵入性。
業(yè)務(wù)指標一定要確定好,不然埋點痛苦,查詢也痛苦。
這里還沒有涉及到告警相關(guān)的內(nèi)容,后面有時間再寫一個告警相關(guān)的。
文中示例代碼:
https://github.com/catcherwong-archive/2020/tree/master/08/PromDemo
總結(jié)
以上是生活随笔為你收集整理的基于Prometheus和Grafana打造业务监控看板的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UEFI + GPT 启动 VHD
- 下一篇: 简单快速导出word文档