.NET Core使用App.Metrics監控訊息佇列(一):初探
一、簡介
App Metrics是一個開放原始碼和跨平臺的.NET庫,用於記錄應用程式中的指標。App Metrics可以在.NET Core或也支援.NET 4.5.2的完整.NET框架上執行。
App Metrics通過在記憶體中進行取樣和聚合,並提供可擴充套件性點以指定間隔將指標重新整理到儲存庫中,從而抽象化了Metrics的基礎儲存庫,例如InfluxDB,Prometheus,Graphite,Elasticsearch等。
App Metrics提供了各種度量標準型別來度量事物,例如請求率,計算一段時間內的使用者登入數,度量執行資料庫查詢所花費的時間,度量可用記憶體的數量等等。支援的指標型別包括Apdex,儀表,計數器,儀表,直方圖和計時器。
App Metrics還提供了執行狀況檢查系統,使您可以通過使用者定義的檢查來監視應用程式的執行狀況。
使用App Metrics,可以:
- 捕獲任何型別的.NET應用程式中的應用程式指標,例如Windows Service,MVC Site,Web API等
- 自動測量MVC或Web API專案中每個端點的效能和錯誤
- 使用OAuth2保護API時,自動衡量每個客戶端的請求率和錯誤率
- 選擇儲存捕獲的指標的位置以及希望用來視覺化這些指標的儀表板
- 通過特定於TSDB的報告擴充套件支援基於推和拉的指標收集,並通過HTTP以要求的格式公開指標
- 支援以所需格式將指標推送到自定義HTTP端點
- 支援以所需格式將指標寫入檔案以供指標代理收集、
更多使用方式直接訪問官網:https://www.app-metrics.io/
二、實際業務場景
上面介紹了App.Metrics以及它支援的場景,但是讀完你一定會覺得很抽象,沒錯我也一樣。如果不是帶著實際的業務場景去看這些東西,其實還是有點雲裡霧裡的。在實際的業務中我們通常會把它用於兩個方面,一方面是包括CPU、記憶體在內的對系統級別的整體監控,園子裡有很多文章都做了demo供大家參考,大家可以搜一下。另外一方面是通過埋點的方式統計相關資料,後端通常使用InfluxDB作為資料庫,並使用Grafana或者Prometheus來對資料進行展示。
本篇將介紹的使用方式是第二鍾,通過埋點的方式來對訊息佇列進行統計,統計的資料包括 佇列數量、每個隊列當前訊息數量(已消費、未消費),以及訊息的生成和釋出速率。
最後的樣子大體就是下面這個樣子:
三、InfluxDB
在使用App.Metrics之前,我們需要先準備好資料庫,也就是InfluxDB,首先快速瞭解一下InfluxDB是什麼:
InfluxDB 是用Go語言編寫的一個開源分散式時序、事件和指標資料庫,無需外部依賴。
類似的資料庫有Elasticsearch、Graphite等。
其主要特色功能
1)基於時間序列,支援與時間有關的相關函式(如最大,最小,求和等)
2)可度量性:你可以實時對大量資料進行計算
3)基於事件:它支援任意的事件資料
InfluxDB的主要特點
1)無結構(無模式):可以是任意數量的列
2)可拓展的
3)支援min, max, sum, count, mean, median 等一系列函式,方便統計
4)原生的HTTP支援,內建HTTP API
5)強大的類SQL語法
6)自帶管理介面,方便使用
Influx包含以下屬性:
database: 資料庫名,在 InfluxDB 中可以建立多個數據庫,不同資料庫中的資料檔案是隔離存放的,存放在磁碟上的不同目錄。
retention policy: 儲存策略,用於設定資料保留的時間,每個資料庫剛開始會自動建立一個預設的儲存策略 autogen,資料保留時間為永久,之後使用者可以自己設定,例如保留最近2小時的資料。插入和查詢資料時如果不指定儲存策略,則使用預設儲存策略,且預設儲存策略可以修改。InfluxDB 會定期清除過期的資料。
measurement: 測量指標名,例如 cpu_usage 表示 cpu 的使用率。
tag sets: tags 在 InfluxDB 中會按照字典序排序,不管是 tagk 還是 tagv,只要不一致就分別屬於兩個 key,例如 host=server01,region=us-west
和 host=server02,region=us-west
就是兩個不同的 tag set。
field name: 例如上面資料中的 value
就是 fieldName,InfluxDB 中支援一條資料中插入多個 fieldName,這其實是一個語法上的優化,在實際的底層儲存中,是當作多條資料來儲存。
timestamp: 每一條資料都需要指定一個時間戳,在 TSM 儲存引擎中會特殊對待,以為了優化後續的查詢操作。
2)Point
InfluxDB 中單條插入語句的資料結構,series + timestamp 可以用於區別一個 point,也就是說一個 point 可以有多個 field name 和 field value。
3)Series
series 相當於是 InfluxDB 中一些資料的集合,在同一個 database 中,retention policy、measurement、tag sets 完全相同的資料同屬於一個 series,同一個 series 的資料在物理上會按照時間順序排列儲存在一起。
series 的 key 為 measurement + 所有 tags 的序列化字串,這個 key 在之後會經常用到。
四、搭建InfuxDB+Grafana
OK,這篇是一個DEMO演示篇,所以我們使用Dokcer快速的建立InfluxDB和Grafana:
docker run -d -p 8083:8083 -p 8086:8086 --expose 8090 --expose 8099 tutum/influxdb
docker run -d --name=grafana -p 3000:3000 grafana/grafana
執行成功之後我們分別可以訪問8083埠的InfluxDB和3000埠的Grafana:
我們首先給InfluxDB新增一個使用者:
新增完成後配置一下Grafana:
四、.NET CORE使用App.Metrics
這裡我們使用.net core控制檯專案來演示(API專案例子已經有很多了,但是控制檯專案沒看到),新建一個控制檯專案 AppMetricsPractice:
通過NuGet引用App.Metrics和App.Metrics.Reporting.InfluxDB
然後我們就可以愉快的使用了,簡單使用可以如下:
static void Main(string[] args) { var metrics = new MetricsBuilder().Report .ToInfluxDb("http://47.99.92.76:8086", "metricsdatabase") .Build(); var counter = new CounterOptions { Name = "my_counter", MeasurementUnit = Unit.Calls }; metrics.Measure.Counter.Increment(counter,"MqQueueNmae"); var task = Task.Run(async () => { await Task.WhenAll(metrics.ReportRunner.RunAllAsync()); }); task.Wait(); Console.Read(); }
使用方式在官網有簡介,這裡介紹一下,ToInfluxDb(influxDB url,InfluxDB databaseName),這裡是InfluxDB的地址和資料庫名稱,如果沒有改資料庫,會自動建立。
以上寫法是簡寫,當然我們可以詳細的控制InfluxDB的屬性,通過以下寫法:
var metrics = new MetricsBuilder() .Report.ToInfluxDb( options => { options.InfluxDb.BaseUri = new Uri("http://47.99.92.76:8086"); options.InfluxDb.Database = "metricsdatabase"; options.InfluxDb.Consistenency = "consistency"; options.InfluxDb.UserName = "admin"; options.InfluxDb.Password = "password"; options.InfluxDb.RetentionPolicy = "rp"; options.InfluxDb.CreateDataBaseIfNotExists = true; options.HttpPolicy.BackoffPeriod = TimeSpan.FromSeconds(30); options.HttpPolicy.FailuresBeforeBackoff = 5; options.HttpPolicy.Timeout = TimeSpan.FromSeconds(10); options.MetricsOutputFormatter = new MetricsInfluxDbLineProtocolOutputFormatter(); options.Filter = filter; options.FlushInterval = TimeSpan.FromSeconds(20); }) .Build();
Option | Description |
---|---|
MetricsOutputFormatter | 向InfluxDB報告指標時使用的格式化程式。 |
Filter | 該過濾器僅用於為此報告者過濾指標。 |
FlushInterval | 向InfluxDB報告指標之間的延遲。 |
InfluxDb.Database | 報告指標的InfluxDB資料庫。 |
InfluxDb.BaseUri | InfluxDB伺服器的URI。 |
InfluxDb.UserName | 使用基本身份驗證與InfluxDB進行身份驗證時的使用者名稱。 |
InfluxDb.Password | 使用基本身份驗證與InfluxDB進行身份驗證時使用的密碼。 |
InfluxDb.Consistenency | 要使用的InfluxDB資料庫一致性級別。 |
InfluxDb.RetentionPolicy | InfluxDB資料庫保留策略以向其寫入指標。 |
InfluxDb.CreateDataBaseIfNotExists | 如果指定的influxdb資料庫不存在,將嘗試建立該資料庫。 |
HttpPolicy.BackoffPeriod | TimeSpan 當指標無法向指標入口端點報告時,從後退。 |
HttpPolicy.FailuresBeforeBackoff | 指標未能向指標入口端點報告時,在回退之前的失敗次數。 |
HttpPolicy.Timeout | 嘗試向度量標準入口端點報告度量標準時的HTTP超時持續時間。 |
然後我們要儲存一個Counter型別的資料,App.Metrics裡有主要有6種資料型別:Counter、Gauge、Histograms 、Meter 、Timer 、Apdex。我們本篇主要使用Counter和Gauge這兩種資料型別,
CounterOptions種的Name是資料表名,MeasurementUnit是測量的內容的描述。
metrics.Measure.Counter.Increment(counter,"MqQueueNmae"); 會往把“my_counter”表裡的value + 1,實際就是對value加加減減,大致如下:
同時還會建立一張名為my_counter__items的表,同時為一個欄位為“MqQueueNmae”的value+1,如下:
多了幾個欄位,通過這個我們可以用來對不同的訊息度列Queue進行統計,而第一張表則當做一張當前消費訊息的統計表。
var task = Task.Run(async () => { await Task.WhenAll(metrics.ReportRunner.RunAllAsync()); }); task.Wait();
這句程式碼是指將當前的統計資料報告到InfluDB,這段程式碼一定要在最後,它會將資料傳送到所有已註冊的儲存端,比如你同時註冊了InfluxDB和Prometheus,那麼資料會同時傳送到這兩個儲存端。
執行完成後建立的兩張表如下:
然後我們就可以去Granfan裡自定義統計圖了,比較簡單,大家可以自己研究一下,大致如下:
下一篇將會把這一套整合到實際專案中,用來監控訊息佇列系統,這一篇只是瞭解,等我明天寫可以直接用於生產