.NET 6服务与Systemd交互实现冻结检测及自动重启方案咨询
解决方案
思路1:升级Tmds.Systemd到最新版本
Tmds.Systemd 0.8.0确实没有Daemon类,该类是在1.0及以上版本中引入的。升级依赖包后即可直接使用封装好的看门狗ping方法:
- 执行NuGet包更新命令:
dotnet add package Tmds.Systemd --version 1.4.0 - 在代码中定时发送看门狗信号(发送间隔需小于
WatchdogSec配置值,比如设为20秒):using Tmds.Systemd; // 可在业务定时器逻辑中添加,或单独启动定时任务 Daemon.Notify(Watchdog: true); // 也可调用更明确的方法:Daemon.SendWatchdogPing();
思路2:手动实现Systemd看门狗通知(无需第三方库)
如果不想升级依赖,可直接基于Systemd原生机制实现:通过环境变量NOTIFY_SOCKET获取通信套接字,手动发送WATCHDOG=1消息。
代码示例:
using System; using System.Net.Sockets; using System.Text; public static void SendSystemdWatchdogPing() { var notifySocket = Environment.GetEnvironmentVariable("NOTIFY_SOCKET"); if (string.IsNullOrEmpty(notifySocket)) return; using var socket = new Socket(AddressFamily.Unix, SocketType.Dgram, ProtocolType.Unspecified); try { // 处理abstract socket(路径以@开头的情况) var endpointPath = notifySocket.StartsWith("@") ? notifySocket.Substring(1) : notifySocket; var endpoint = new UnixDomainSocketEndPoint(endpointPath); var message = Encoding.UTF8.GetBytes("WATCHDOG=1"); socket.SendTo(message, endpoint); } catch { // 忽略发送失败,Systemd会在超时后自动重启服务 } }
在定时器逻辑中调用该方法即可,发送间隔需小于WatchdogSec配置值。
思路3:使用.NET官方Systemd集成包
.NET提供官方的Microsoft.Extensions.Hosting.Systemd包,原生支持Systemd通知与看门狗功能,推荐优先使用:
- 添加NuGet包:
dotnet add package Microsoft.Extensions.Hosting.Systemd - 配置Host启用Systemd集成:
using Microsoft.Extensions.Hosting; var host = Host.CreateDefaultBuilder(args) .UseSystemd() .ConfigureServices(services => { services.AddHostedService<YourTimerService>(); }) .Build(); await host.RunAsync(); - 在定时服务中注入
SystemdLifetime并发送看门狗信号:using Microsoft.Extensions.Hosting; using System.Threading; using System.Threading.Tasks; public class YourTimerService : IHostedService, IDisposable { private Timer _timer; private readonly SystemdLifetime _systemdLifetime; public YourTimerService(IHostLifetime hostLifetime) { _systemdLifetime = (SystemdLifetime)hostLifetime; } public Task StartAsync(CancellationToken cancellationToken) { // 定时间隔需小于WatchdogSec配置值,示例设为20秒 _timer = new Timer(ExecuteTask, null, TimeSpan.Zero, TimeSpan.FromSeconds(20)); return Task.CompletedTask; } private void ExecuteTask(object state) { // 执行你的业务逻辑 // ... // 发送看门狗保活信号 _systemdLifetime.NotifyWatchdog(); } public Task StopAsync(CancellationToken cancellationToken) { _timer?.Change(Timeout.Infinite, 0); return Task.CompletedTask; } public void Dispose() { _timer?.Dispose(); } }
注意事项
无论采用哪种方案,发送看门狗信号的间隔必须小于Systemd配置中的WatchdogSec值(比如配置为30秒时,发送间隔设为20-25秒),避免Systemd误判服务冻结。
内容的提问来源于stack exchange,提问作者FelipeFonsecabh
相关产品推荐
相关产品推荐

