c# - 为长时间运行的进程 .Net Core 实施 HealthChecks
问题描述
我有一个长期运行的进程:IHostedService。它整天运行,调用不同的外部 api(服务)来提取数据。如果在此过程中任何这些外部服务失败/抛出异常,该过程花费的时间超过 30 分钟等,我想得到通知。我将如何设置它?
经过一番研究,我最终得到了这个: https ://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/health-checks?view=aspnetcore-5.0#separate-readiness-and- liveness -probes(StartupHostedServiceHealthCheck 部分)
这是我到目前为止所拥有的:
// Registered as Singleton
public interface IHostedServiceStatus
{
bool IsHostedServiceRunning { get; set; }
DateTime RunTime { get; }
string Message { get; }
void Setup(string name, DateTime runTime, string message = null);
}
public class HostedServiceStatus : IHostedServiceStatus
{
private string _message;
private string _name;
public string Message => $"HostedService {_name} started on: {RunTime} failed to complete. {_message}";
public bool IsHostedServiceRunning { get; set; }
public DateTime RunTime { get; private set; }
public void Setup(string name, DateTime runTime, string message = null)
{
_name = name;
RunTime = runTime;
IsHostedServiceRunning = true;
if (!string.IsNullOrEmpty(message))
_message = message;
}
}
// HealthCheck
public class HostedServiceHealthCheck : IHealthCheck
{
private readonly IHostedServiceStatus _hostedServiceStatus;
private readonly TimeSpan _duration = TimeSpan.FromMinutes(30);
public HostedServiceHealthCheck(IHostedServiceStatus hostedServiceStatus)
{
_hostedServiceStatus = hostedServiceStatus;
}
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default)
{
if (_hostedServiceStatus.IsHostedServiceRunning)
{
if (_hostedServiceStatus.RunTime.Subtract(DateTime.Now).Duration() >= _duration)
return Task.FromResult(
HealthCheckResult.Unhealthy(_hostedServiceStatus.Message));
}
return Task.FromResult(
HealthCheckResult.Healthy("Task is finished."));
}
}
// Long running process
public async void Process(object state)
{
// each service runs about 10 min
foreach (var externalService in externalServices)
{
try
{
_hostedServiceStatus.Setup(externalService.Name, DateTime.Now); // setup healthcheckStatus - injected
...
// calls externalService gets data and saves to db
_dataMinerStatus.IsHostedServiceRunning = false; // udpate Healthcheck - finished successfully
}
catch (Exception ex)
{
// set MInDateTime so that it becamse UnHealthy
_hostedServiceStatus.Setup(externalService.Name, DateTime.MinValue);
// HealthCheck injected
await _healthCheck.CheckHealthAsync(new HealthCheckContext()); // send notification? (webhook setup) - will this work?
}
}
解决方案
推荐阅读
- java - 为什么“ig”重复两次?
- oracle-apex - 如何使用 Web 源在 Oracle Apex 中执行 PL/SQL 时修复“ORA-06550”
- asp.net - 清除文本框时显示所有 Gridview 控件值
- ios - 呈现一个新的 ViewController 但维护视图堆栈
- ruby - 如何在 irb 中测试 parslet atom
- python-3.x - 根据节点pyspark的数量拆分我的数据框
- c# - 测试减法并在结果大于零时应用它
- python - 将 JSON 数据提取到关系表中
- c# - 使用 BigINtegers 的并行 for 循环
- c - 通过 uart (esp-idf) 的 esp32 printf 通道