在.NET Core Worker Service中实现运行状况检查的最佳方法是什么?
该服务将在docker内部运行,并且需要能够检查该服务的运行状况。
在.NET Core Worker Service中实现运行状况检查的最佳方法是什么?
该服务将在docker内部运行,并且需要能够检查该服务的运行状况。
我认为将 SDK 更改为 Microsoft.NET.Sdk.Web 不值得。你会因为一次健康检查而包含额外的中间件吗?不用谢...
您可以做的是使用不同的协议,如 TCP。
总体思路是:
如果您需要更详细的信息,您可以查看:Monitoring Health of ASP.NET Core Background Services With TCP Probes on Kubernetes
干杯!
,执行此操作的另一种方法是实现IHealthCheckPublisher
。
这种方法的好处是能够重用您现有的IHealthCheck
或与依赖IHealthCheck
接口(例如this one)的第三方库进行集成。
尽管您仍将Microsoft.NET.Sdk.Web
定位为SDK,但不需要添加任何asp.net细节。
这里是一个例子:
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host
.CreateDefaultBuilder(args)
.ConfigureServices((hostContext,services) =>
{
services
.AddHealthChecks()
.AddCheck<RedisHealthCheck>("redis_health_check")
.AddCheck<RfaHealthCheck>("rfa_health_check");
services.AddSingleton<IHealthCheckPublisher,HealthCheckPublisher>();
services.Configure<HealthCheckPublisherOptions>(options =>
{
options.Delay = TimeSpan.FromSeconds(5);
options.Period = TimeSpan.FromSeconds(5);
});
});
}
public class HealthCheckPublisher : IHealthCheckPublisher
{
private readonly string _fileName;
private HealthStatus _prevStatus = HealthStatus.Unhealthy;
public HealthCheckPublisher()
{
_fileName = Environment.GetEnvironmentVariable(EnvVariableNames.DOCKER_HEALTHCHECK_FILEPATH) ??
Path.GetTempFileName();
}
public Task PublishAsync(HealthReport report,CancellationToken cancellationToken)
{
// AWS will check if the file exists inside of the container with the command
// test -f $DOCKER_HEALTH_CHECK_FILEPATH
var fileExists = _prevStatus == HealthStatus.Healthy;
if (report.Status == HealthStatus.Healthy)
{
if (!fileExists)
{
using var _ = File.Create(_fileName);
}
}
else if (fileExists)
{
File.Delete(_fileName);
}
_prevStatus = report.Status;
return Task.CompletedTask;
}
}
,
要做到这一点,我将Microsoft.NET.Sdk.Web添加到了Worker中,然后将一个Web主机配置为与Worker一起运行:
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(builder =>
{
builder.UseStartup<Startup>();
})
.ConfigureServices((hostContext,services) =>
{
services.AddHostedService<Worker>();
services.AddLogging(builder =>
builder
.AddDebug()
.AddConsole()
);
});
完成此操作后,剩下要做的就是map the health check endpoint,就像通常使用ASP.NET Core一样。
,我认为您还应该考虑保留Microsoft.NET.Sdk.Worker。
不要仅仅因为运行状况检查而更改整个SDK。
然后,您可以创建一个backgroundservice(就像main worker一样),以便更新文件以写入例如当前时间戳。后台健康检查工作者的示例为:
public class HealthCheckWorker : BackgroundService
{
private readonly int _intervalSec;
private readonly string _healthCheckFileName;
public HealthCheckWorker(string healthCheckFileName,int intervalSec)
{
this._intervalSec = intervalSec;
this._healthCheckFileName = healthCheckFileName;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (true)
{
File.WriteAllText(this._healthCheckFileName,DateTime.UtcNow.ToString());
await Task.Delay(this._intervalSec * 1000,stoppingToken);
}
}
}
然后,您可以添加如下扩展方法:
public static class HealthCheckWorkerExtensions
{
public static void AddHealthCheck(this IServiceCollection services,string healthCheckFileName,int intervalSec)
{
services.AddHostedService<HealthCheckWorker>(x => new HealthCheckWorker(healthCheckFileName,intervalSec));
}
}
您可以通过此服务添加健康检查支持
.ConfigureServices(services =>
{
services.AddHealthCheck("hc.txt",5);
})