Skip to content

Commit

Permalink
改进systemd对服务的管理,增强兼容性
Browse files Browse the repository at this point in the history
  • Loading branch information
andywu188 committed Jun 2, 2024
1 parent 10b0019 commit 311b230
Showing 1 changed file with 38 additions and 13 deletions.
51 changes: 38 additions & 13 deletions NewLife.Agent/Systemd.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,12 @@ public override Boolean IsRunning(String serviceName)
{
//某些服务状态为active (exited)时,通常是因为服务配置中使用了 Type=forking 类型,而 systemd 误认为主进程已经退出
//所以需要进一步检查,例如:nginx、redis等
str = Execute("systemctl", $"show {serviceName} -p Type", false);
if (!str.IsNullOrEmpty() && str.Contains("=forking"))
var file = GetServicePath(serviceName);
if (file != null && file.StartsWith("/etc/init.d"))
{
//此方案并不完美,但是可以解决大部分情况
//pgrep -a {serviceName}
str = Execute("pgrep", $"-a {serviceName}", false);
if (!str.IsNullOrEmpty())
//SysVinit 服务,可以使用 /etc/init.d/{serviceName} status 命令检查服务状态
str = Execute($"/etc/init.d/{serviceName}", "status", false);
if (!str.IsNullOrEmpty() && str.Contains("running"))
{
return true;
}
Expand Down Expand Up @@ -222,7 +221,16 @@ public override Boolean Start(String serviceName)
{
XTrace.WriteLine("{0}.Start {1}", Name, serviceName);

return Process.Start("systemctl", $"start {serviceName}") != null;
var file = GetServicePath(serviceName);
if (file != null && file.StartsWith("/etc/init.d"))
{
//SysVinit 服务,可以使用 /etc/init.d/{serviceName} start 命令启动服务
return Process.Start($"/etc/init.d/{serviceName}", "start") != null;
}
else
{
return Process.Start("systemctl", $"start {serviceName}") != null;
}
}

/// <summary>停止服务</summary>
Expand All @@ -231,8 +239,16 @@ public override Boolean Start(String serviceName)
public override Boolean Stop(String serviceName)
{
XTrace.WriteLine("{0}.Stop {1}", Name, serviceName);

return Process.Start("systemctl", $"stop {serviceName}") != null;
var file = GetServicePath(serviceName);
if (file != null && file.StartsWith("/etc/init.d"))
{
//SysVinit 服务,可以使用 /etc/init.d/{serviceName} stop 命令停止服务
return Process.Start($"/etc/init.d/{serviceName}", "stop") != null;
}
else
{
return Process.Start("systemctl", $"stop {serviceName}") != null;
}
}

/// <summary>重启服务</summary>
Expand All @@ -241,10 +257,19 @@ public override Boolean Restart(String serviceName)
{
XTrace.WriteLine("{0}.Restart {1}", Name, serviceName);

//if (InService)
return Process.Start("systemctl", $"restart {serviceName}") != null;
//else
// return Process.Start(Service.GetExeName(), "-run -delay") != null;
var file = GetServicePath(serviceName);
if (file != null && file.StartsWith("/etc/init.d"))
{
//SysVinit 服务,可以使用 /etc/init.d/{serviceName} restart 命令重启服务
return Process.Start($"/etc/init.d/{serviceName}", "restart") != null;
}
else
{
//if (InService)
return Process.Start("systemctl", $"restart {serviceName}") != null;
//else
// return Process.Start(Service.GetExeName(), "-run -delay") != null;
}
}

private static String Execute(String cmd, String arguments, Boolean writeLog = true)
Expand Down

1 comment on commit 311b230

@nnhy
Copy link
Member

@nnhy nnhy commented on 311b230 Jun 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

仔细阅读源码,发现sysvinit和systemd是两个不同的命令,它们的机制和用法大体相同,但是在细节上有许多不同的地方。
我建议新增一种IHost主机,把二次分开。然后在Agent初始化时检测需要使用哪一种。

Please sign in to comment.