系列導航及源代碼
需求
應用健康檢查在容器部署的微服務場景下非常常見,相比而言單體非容器部署的應用就不太關心這個特性,為了后續的內容我們在本文中簡單介紹一下如何實現應用程序的健康檢查功能。
目標
實現TodoList
的健康檢查功能。
原理與思路
.NET框架從.NET Core 2.2版本開始引入了相關的功能,同時AspNetCore.Diagnostics.HealthChecks包提供了更為豐富的健康檢查功能,包括數據庫,消息總線,Redis和ElasticSearch的健康檢查。
健康檢查探針(probe)分為三種:
- readiness probes:應用程序就緒探針,判斷當前應用程序是否已經啟動。
- liveness probes: 應用程序存活探針,判斷當前應用程序是否出於活動狀態。
- startup probes:應用程序功能探針,一般我們用
hc
來表示其端口,可以用來判斷應用程序內部功能是否正常(比如判斷數據庫連接是否正常,判斷Redis連接是否正常之類)。
在本文中我們不過多地發散,通過創建一個自定義的健康檢查對象來實現。
實現
自定義健康檢查,實現IHealthCheck接口
Microsoft.Extensions.Diagnostics.HealthChecks
using Microsoft.Extensions.Diagnostics.HealthChecks;
namespace TodoList.Application.Common;
public class ApplicationHealthCheck : IHealthCheck
{
private static readonly Random _rnd = new ();
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
var result = _rnd.Next(5) == 0
? HealthCheckResult.Healthy()
: HealthCheckResult.Unhealthy("Failed random");
return Task.FromResult(result);
}
}
添加服務和中間件
首先在Application/DependencyInjection
中添加健康檢查服務:
DependencyInjection.cs
services.AddHealthChecks().AddCheck<ApplicationHealthCheck>("Random Health Check");
然后修改Program
中間件配置如下:
Program.cs
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseHttpLogging();
app.MapDefaultControllerRoute();
app.MapHealthChecks("/liveness");
app.MapHealthChecks("/ready");
app.MapHealthChecks("/hc");
驗證
啟動Api
項目,執行健康檢查的三個GET
接口,截圖我只貼其中一個,因為我們在實現健康檢查的時候,采用了隨機數返回Healthy
或者Unhealthy
的方式,所以多請求幾次,應該能看到下面的響應:
一點擴展
關於Smart probes和Dumb probes
- 所謂
Smart probes
最典型的目的就是為了驗證應用程序是否能正確工作,像一開始所說的,它可以用來探測外部依賴如數據庫、消息隊列、甚至是其他API的連接是否正常,程序在這些地方是否可以按預期工作。 - 相對而言,
Dumb probes
典型的應用目的是用來判斷應用程序沒有崩潰,它並不檢查功能及依賴上的正確性,通常表現為HTTP的直接響應。
推薦的使用方式是:
- 對於
liveness
檢查,使用dumb probes
就可以了,因為只要能夠響應HTTP請求,就可以證明應用程序沒有崩潰。 - 對於
startup
或者稱作真正的“健康”檢查hc
,使用smart probes
,因為這時候不僅要保證程序沒有崩潰,我們還需要某種程度的功能及依賴的健康檢查,以證明程序能夠按預期工作。 - 對於
readiness
檢查,需要根據實際的需求來看,如果我們沒有定義特殊的應用程序“就緒”標准,使用dumb probes
就可以;反之如果我們需要進行某種程度的邏輯檢查來定義“就緒”,那么就需要使用smart probes
。
設置Dumb健康檢查接口
修改中間件配置:
Program.cs
app.MapHealthChecks("/liveness", new HealthCheckOptions { Predicate = r => r.Name.Contains("self") });
app.MapHealthChecks("/ready", new HealthCheckOptions { Predicate = _ => false });
這時候我們再去請求健康檢查,這兩個接口已經固定返回Healthy
結果了,hc接口依然按照我們之前設置的進行隨機返回。
總結
本文我們簡單地實現了健康檢查接口,目前還不太能看得出來作用,但是當我們進行容器化部署,或是進行k8s部署時,健康檢查探針的作用就比較明顯了。關於健康檢查,更多用法請參考官方文檔:Health checks in ASP.NET Core