chu*_*1ty 13
我认为将 SDK 更改为Microsoft.NET.Sdk.Web不值得。您会仅仅因为一项健康检查而包含额外的中间件吗?不,谢谢 ...
您可以做的是使用不同的协议,例如 TCP。
总体思路是:
如果您需要更详细的信息,您可以查看:Monitoring Health of ASP.NET Core Background Services With TCP Probes on Kubernetes
干杯!
kam*_*nzo 10
添加 HTTPListener 并公开运行状况检查端点。
使用HTTPListener不需要添加Microsoft.NET.Sdk.Web SDK。
程序.cs
using Consumer;
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddHostedService<Worker>();
services.AddHostedService<HttpHealthcheck>();
})
.Build();
await host.RunAsync();
Run Code Online (Sandbox Code Playgroud)
HttpHealthcheck.cs
using System.Net;
using System.Text;
namespace Consumer;
public class HttpHealthcheck : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly HttpListener _httpListener;
private readonly IConfiguration _configuration;
public HealthcheckHttpListener(ILogger<Worker> logger, IConfiguration configuration)
{
_logger = logger;
_configuration = configuration;
_httpListener = new HttpListener();
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_httpListener.Prefixes.Add($"http://*:5001/healthz/live/");
_httpListener.Prefixes.Add($"http://*:5001/healthz/ready/");
_httpListener.Start();
_logger.LogInformation($"Healthcheck listening...");
while (!stoppingToken.IsCancellationRequested)
{
HttpListenerContext ctx = null;
try
{
ctx = await _httpListener.GetContextAsync();
}
catch (HttpListenerException ex)
{
if (ex.ErrorCode == 995) return;
}
if (ctx == null) continue;
var response = ctx.Response;
response.ContentType = "text/plain";
response.Headers.Add(HttpResponseHeader.CacheControl, "no-store, no-cache");
response.StatusCode = (int)HttpStatusCode.OK;
var messageBytes = Encoding.UTF8.GetBytes("Healthy");
response.ContentLength64 = messageBytes.Length;
await response.OutputStream.WriteAsync(messageBytes, 0, messageBytes.Length);
response.OutputStream.Close();
response.Close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是实现IHealthCheckPublisher.
这种方法的好处是能够重用您现有的IHealthChecks 或与依赖于IHealthCheck接口的3rd 方库(如这个)集成。
尽管您仍然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;
}
}
Run Code Online (Sandbox Code Playgroud)
我认为您还应该考虑保留 Microsoft.NET.Sdk.Worker。
不要仅仅因为健康检查而改变整个sdk。
然后您可以创建一个后台服务(就像主工作人员一样),以便更新文件以写入例如当前时间戳。后台健康检查工作人员的一个示例是:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以添加一个扩展方法,如下所示:
public static class HealthCheckWorkerExtensions
{
public static void AddHealthCheck(this IServiceCollection services,
string healthCheckFileName, int intervalSec)
{
services.AddHostedService<HealthCheckWorker>(x => new HealthCheckWorker(healthCheckFileName, intervalSec));
}
}
Run Code Online (Sandbox Code Playgroud)
这样您就可以在服务中添加健康检查支持
.ConfigureServices(services =>
{
services.AddHealthCheck("hc.txt", 5);
})
Run Code Online (Sandbox Code Playgroud)
小智 2
为了实现此目的,我所做的是将 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()
);
});
Run Code Online (Sandbox Code Playgroud)
完成此操作后,剩下要做的就是映射运行状况检查端点,就像通常使用 ASP.NET Core 所做的那样。
| 归档时间: |
|
| 查看次数: |
6739 次 |
| 最近记录: |