上篇我們講了如何使用App Metrics 做一個簡單的APM監控,最后提到過健康檢查這個東西.
這篇主要就是講解健康檢查的內容.
沒看過上篇的,請移步:ASP.NET Core之跨平台的實時性能監控
首先我們來了解一下什么是健康檢查(health checks)?
1.什么是健康檢查?
健康檢查,其實這個名稱已經很明確了,它是檢查你的應用程序是否健康運行的一種方式。隨着當前各類項目越來越多的應用程序正在轉向微服務式架構,健康檢查就變得尤為關鍵。雖然微服務體系結構具有許多好處,但其中一個缺點就是為了確保所有這些服務都正常運行的操作開銷更高。你不在是監視一個龐大的整體項目的健康狀況,而是需要監控許多不同服務的狀態,甚至這些服務通常只負責一件事情。健康檢查(Heatlh Checks)通常與一些服務發現工具結合使用,如Consul ,來監控您的微服務器,來觀測您的服務是否健康運行。
2.如何實施健康檢查?
健康檢查有很多種不同的方法,但最常見的方法是將HTTP端點暴露給專門用於健康檢查的應用程序。一般來說,如果一切情況都很好,你的服務將返回200的狀態碼,然而任何非200的代碼則意味着出現問題。例如,如果發生錯誤,你可能會返回500以及一些出錯的JSON信息。
3.健康檢查的常見情況
你的健康檢查將基於你的應用程序或者你的微服務主要在做寫什么事情,就檢查什么.
不過我們也可以舉例一些常見的健康檢查內容:
- 檢查我的服務可以連接到數據庫嗎?
- 檢查我的服務可以查詢第三方API嗎?
- 可能做一些只讀操作
- 我的服務可以訪問文件系統嗎(IO是否正常)?
- 檢查我的服務占用的內存或CPU是否高於某個閾值?
下面我們就來講解一下,如何使用App Metrics來實現我們的健康檢查.
效果如圖:
這里就不創建新的項目了,直接拿上個項目的例子來寫.
App Metrics中的健康檢查分為3種狀態:
1.健康(綠),2.亞健康(黃),3.不健康(紅). 顏色如上圖所示
也含有一些內置的健康檢查(后面講解),我們先來講一下如何自行創建健康檢查
1.創建自己的健康檢查
首先我們在Demo中創建一個健康檢查的文件夾(當然,也可以是類庫)
創建類,取名為 OKHealthCheck,繼承HealthCheck(引用:using App.Metrics.Health),代碼如下:
public class OKHealthCheck: HealthCheck { public OKHealthCheck() : base("正常的檢查(OKHealthCheck)") { } protected override Task<HealthCheckResult> CheckAsync(CancellationToken token = default(CancellationToken)) { //返回正常的信息 return Task.FromResult(HealthCheckResult.Healthy("OK")); } }
然后在Startup注入中,加入健康檢查的注入
services.AddMetrics(options => { options.GlobalTags.Add("app", "sample app"); options.GlobalTags.Add("env", "stage"); }) .AddHealthChecks()//這里是健康檢查的注入 .AddJsonSerialization() .AddReporting( factory => { factory.AddInfluxDb( new InfluxDBReporterSettings { InfluxDbSettings = new InfluxDBSettings(database, uri), ReportInterval = TimeSpan.FromSeconds(5) }); }) .AddMetricsMiddleware(options => options.IgnoredHttpStatusCodes = new[] { 404 });
值得注意的是,這里的健康檢查注入,是通過反射實現的,他會自動檢測你項目引用的dll,找到繼承過HealthCheck的類,自動全部注入.
然后我們運行,會發現我們的Grafana的健康檢查儀表盤,多了條數據,如圖:
(注:這里說明一下這個Apdex Score(用戶滿意度得分),是默認自動開啟的.可以通過配置關閉)
上面我們演示了如何創建一個自己的健康檢查,但是只返回了健康的信息,我們還有亞健康,不健康,這些當然也是會出現的.所以,代碼如下:
返回不健康的信息:
protected override Task<HealthCheckResult> CheckAsync(CancellationToken token = default(CancellationToken)) { return Task.FromResult(HealthCheckResult.Unhealthy("不健康")); //重點是這里 }
返回亞健康
protected override Task<HealthCheckResult> CheckAsync(CancellationToken token = default(CancellationToken)) { return Task.FromResult(HealthCheckResult.Degraded("Degraded")); }
在這個方法中,加上你們自己的檢查業務邏輯,返回相應的HealthCheckResult即可.
2.使用內置的健康檢查
前面我們說過,App Metrics給我們提供了一些內置的健康檢查,我們下面就來一一講解
2.1內置的HTTP檢測
我們直接在AddHealthChecks中注入,使用方法如下,:
.AddHealthChecks(factory=> { //通過HTTP訪問GitHub,看是否正常,間隔10秒 factory.RegisterHttpGetHealthCheck("github是否訪問正常", new Uri("https://github.com/"), TimeSpan.FromSeconds(10)); })//這里是健康檢查的注入
2.2內置的Ping檢測
代碼如下:
.AddHealthChecks(factory=> { //通過HTTP訪問GitHub,看是否正常,間隔10秒 factory.RegisterHttpGetHealthCheck("github是否訪問正常", new Uri("https://github.com/"), TimeSpan.FromSeconds(10)); //檢測是否能Ping通百度 factory.RegisterPingHealthCheck("百度 ping", "baidu.com", TimeSpan.FromSeconds(10)); })//這里是健康檢查的注入
2.3內置物理內存占用檢測
說明一下,這個是檢測當前程序占用的物理內存是否超過你設置閥值(字節為單位),並不是檢測你還剩下多少物理內存
.AddHealthChecks(factory=> { //通過HTTP訪問GitHub,看是否正常,間隔10秒 factory.RegisterHttpGetHealthCheck("github是否訪問正常", new Uri("https://github.com/"), TimeSpan.FromSeconds(10)); //檢測是否能Ping通百度 factory.RegisterPingHealthCheck("百度 ping", "baidu.com", TimeSpan.FromSeconds(10)); //檢測占用內存是否超過2G factory.RegisterProcessPhysicalMemoryHealthCheck("占用內存是否超過閥值(2G)", (2048L * 1024L) * 1024L); })//這里是健康檢查的注入
2.4內置專用內存占用檢測
說明一下,這個方法,通過源碼可以看到,獲取的是PrivateMemorySize64,也是就是獲取為關聯的進程分配的專用內存量。
.AddHealthChecks(factory=> { //通過HTTP訪問GitHub,看是否正常,間隔10秒 factory.RegisterHttpGetHealthCheck("github是否訪問正常", new Uri("https://github.com/"), TimeSpan.FromSeconds(10)); //檢測是否能Ping通百度 factory.RegisterPingHealthCheck("百度 ping", "baidu.com", TimeSpan.FromSeconds(10)); //檢測占用內存是否超過2G factory.RegisterProcessPhysicalMemoryHealthCheck("占用內存是否超過閥值(2G)", (2048L * 1024L) * 1024L); //檢測專用內存占用量是否超過閥值(2G) factory.RegisterProcessPrivateMemorySizeHealthCheck("專用內存占用量是否超過閥值(2G)", (2048L * 1024L) * 1024L); })//這里是健康檢查的注入
2.5內置虛擬內存占用檢測
沒啥好說的,直接上代碼:
.AddHealthChecks(factory=> { //通過HTTP訪問GitHub,看是否正常,間隔10秒 factory.RegisterHttpGetHealthCheck("github是否訪問正常", new Uri("https://github.com/"), TimeSpan.FromSeconds(10)); //檢測是否能Ping通百度 factory.RegisterPingHealthCheck("百度 ping", "baidu.com", TimeSpan.FromSeconds(10)); //檢測占用內存是否超過2G factory.RegisterProcessPhysicalMemoryHealthCheck("占用內存是否超過閥值(2G)", (2048L * 1024L) * 1024L); //檢測專用內存占用量是否超過閥值(2G) factory.RegisterProcessPrivateMemorySizeHealthCheck("專用內存占用量是否超過閥值(2G)", (2048L * 1024L) * 1024L); //檢測虛擬內存占用是否超過閥值(2G) factory.RegisterProcessVirtualMemorySizeHealthCheck("虛擬內存占用量是否超過閥值(2G)", (2048L * 1024L) * 1024L); })//這里是健康檢查的注入
最后,我們把代碼跑起來.~,效果如圖
至此,今天的內容就結束了.
有趣的是,其實微軟在ASP.NET Core 2.0中其實也給我們內置了相關的健康檢測插件.(說明健康檢測真的很重要)
https://github.com/dotnet-architecture/HealthChecks
有興趣的朋友可以去看看.