Net Core2.2支持为发布的服务执行health checks。我想缓存一个检查的响应。
我看到我可以使用HealthCheckOptions并为AllowCachingResponses属性设置true
值。
app.UseHealthChecks("/api/services/healthCheck",
new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions()
{
AllowCachingResponses = true
});
但我不明白如何设置时间缓存的数量。设置相应HTTP头(Cache-Control
、Expires
等)的最佳位置是什么?又是如何做到的?
我的服务由IIS发布。
发布于 2019-08-15 23:19:47
您提到的AllowCachingResponses
选项只与HealthCheckMiddleware是否设置HTTP头有关。通常,中间服务器、代理等可以缓存GET请求的结果,并且这些头指示服务器每次都应该重新获取它们。
但是,如果负载均衡器使用这些检查来指示服务是否应该接收更多流量,则它很可能无论如何都不会缓存结果。
为了实现你想要的东西,你需要编写额外的逻辑。一种方法是编写一种HealthCheckCacher
类型,如下所示:
public class HealthCheckCacher : IHealthCheck
{
private readonly SemaphoreSlim _mutex = new SemaphoreSlim(1);
private readonly IHealthCheck _healthCheck;
private readonly TimeSpan _timeToLive;
private HealthCheckResult _result;
private DateTime _lastCheck;
public static readonly TimeSpan DefaultTimeToLive = TimeSpan.FromSeconds(30);
/// <summary>
/// Creates a new HealthCheckCacher which will cache the result for the amount of time specified.
/// </summary>
/// <param name="healthCheck">The underlying health check to perform.</param>
/// <param name="timeToLive">The amount of time for which the health check should be cached. Defaults to 30 seconds.</param>
public HealthCheckCacher(IHealthCheck healthCheck, TimeSpan? timeToLive = null)
{
_healthCheck = healthCheck;
_timeToLive = timeToLive ?? DefaultTimeToLive;
}
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
// you could improve thread concurrency by separating the read/write logic but this would require additional thread safety checks.
// will throw OperationCanceledException if the token is canceled while we're waiting.
await _mutex.WaitAsync(cancellationToken);
try
{
// previous check is cached & not yet expired; just return it
if (_lastCheck > DateTime.MinValue && DateTime.Now - _lastCheck < _timeToLive)
return _result;
// check has not been performed or is expired; run it now & cache the result
_result = await _healthCheck.CheckHealthAsync(context, cancellationToken);
_lastCheck = DateTime.Now;
return _result;
}
finally
{
_mutex.Release();
}
}
}
发布于 2021-08-03 05:53:28
我的API中有一个调度的作业,它调用HealthCheckService.CheckHealthAsync()
并存储HealthReport
结果。然后,我只需创建返回此值的常规API端点。简单得多,不需要人工包装器健康检查。
https://stackoverflow.com/questions/54800413
复制相似问题