.NET控制台应用健康检查失效,文件未按时更新问题排查
问题描述
我参考资料为非HTTP的.NET控制台应用实现健康检查,运行应用后TEMP文件夹生成了新文件,但运行5分钟后文件的最后修改时间仍未变化。我预期健康检查每5秒执行一次,并根据当前分钟数更新文件,怀疑PublishAsync方法未正常工作,请问我哪里出错了?
相关代码
CreateHostBuilder 代码
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseWindowsService() .UseSystemd() .ConfigureLogging(ConfigureLogging) .ConfigureAppConfiguration((hostContext, configApp) => { var environmentName = Environment.GetEnvironmentVariable("env").ToLower(); Console.WriteLine("ENV Variable Code is " + environmentName); ConfigurationManager.AppSettings["EnvType"] = environmentName; configApp .AddJsonFile("appsettings.json", true) .AddJsonFile($"appsettings.{environmentName}.json", true); }) .ConfigureServices((hostContext, services) => { var container = InjectionContainer.Initialize(services); services.AddHostedService(service => { var worker = container.GetInstance<Worker>(); return worker; }); services.AddHealthChecks() .AddCheck("test", () => DateTime.UtcNow.Minute % 2 == 0 ? HealthCheckResult.Healthy() : HealthCheckResult.Unhealthy()); services.AddSingleton<IHealthCheckPublisher, HealthCheckPublisher>(); services.Configure<HealthCheckPublisherOptions>(options => { options.Delay = TimeSpan.FromSeconds(5); options.Period = TimeSpan.FromSeconds(5); }); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
健康检查发布者(HealthCheckPublisher)代码
public class HealthCheckPublisher : IHealthCheckPublisher { private readonly string _fileName; private HealthStatus _prevStatus = HealthStatus.Unhealthy; public HealthCheckPublisher() { _fileName = Path.GetTempFileName(); } /// <summary> /// 创建/更新文件以指示Pod的"健康"状态,删除文件表示"不健康" /// 该文件将被K8s存活探针检测 /// </summary> /// <param name="report"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public Task PublishAsync(HealthReport report, CancellationToken cancellationToken) { var fileExists = _prevStatus == HealthStatus.Healthy; if (report.Status == HealthStatus.Healthy) { using var _ = File.Create(_fileName); } else if (fileExists) { File.Delete(_fileName); } _prevStatus = report.Status; return Task.CompletedTask; } }
问题排查与解决
核心问题1:Web主机配置覆盖了Worker服务的健康检查逻辑
你在配置Host时同时启用了.ConfigureWebHostDefaults,这会把应用切换为Web主机模式,而非纯Worker服务模式。Web主机的健康检查默认依赖HTTP端点,你配置的IHealthCheckPublisher定时执行逻辑不会生效——两种主机模式的健康检查发布机制完全不同。
核心问题2:文件更新仅在状态切换时触发
你的PublishAsync方法只有在健康状态发生变化(健康→不健康/不健康→健康)时才会修改文件。如果当前分钟数一直是偶数(健康状态),文件只会被创建一次,后续不会更新修改时间;如果一直是奇数(不健康状态),文件被删除后就不会再有变动。
修复方案
- 移除Web主机配置:如果这是纯控制台/Worker服务,删掉
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>()),确保Worker服务的健康检查定时发布机制正常启动。 - 修改文件更新逻辑:如果需要每次健康检查都更新文件修改时间,不管状态是否变化,把健康状态下的代码改成:
if (report.Status == HealthStatus.Healthy) { // 用更新写入时间替代重复创建文件,避免不必要的IO开销 if (File.Exists(_fileName)) { File.SetLastWriteTimeUtc(_fileName, DateTime.UtcNow); } else { using var _ = File.Create(_fileName); } }
- 验证服务注册:确认Worker服务的健康检查后台服务已正确注册,移除Web主机配置后,
.AddHealthChecks()配合IHealthCheckPublisher和HealthCheckPublisherOptions的定时配置才能正常生效。
内容的提问来源于stack exchange,提问作者R SP
相关产品推荐
相关产品推荐

