You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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方法只有在健康状态发生变化(健康→不健康/不健康→健康)时才会修改文件。如果当前分钟数一直是偶数(健康状态),文件只会被创建一次,后续不会更新修改时间;如果一直是奇数(不健康状态),文件被删除后就不会再有变动。

修复方案

  1. 移除Web主机配置:如果这是纯控制台/Worker服务,删掉.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>()),确保Worker服务的健康检查定时发布机制正常启动。
  2. 修改文件更新逻辑:如果需要每次健康检查都更新文件修改时间,不管状态是否变化,把健康状态下的代码改成:
if (report.Status == HealthStatus.Healthy)
{
    // 用更新写入时间替代重复创建文件,避免不必要的IO开销
    if (File.Exists(_fileName))
    {
        File.SetLastWriteTimeUtc(_fileName, DateTime.UtcNow);
    }
    else
    {
        using var _ = File.Create(_fileName);
    }
}
  1. 验证服务注册:确认Worker服务的健康检查后台服务已正确注册,移除Web主机配置后,.AddHealthChecks()配合IHealthCheckPublisher和HealthCheckPublisherOptions的定时配置才能正常生效。

内容的提问来源于stack exchange,提问作者R SP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 10:42:10