我在一个小型物联网项目中有以下依赖项:
MySqlServer < 设备服务器 < Web 服务器
如果没有启动和设置 MySqlServer,则 DeviceServer 无法启动;如果没有 Device Server,则 Web 服务器无法启动。
我用Requires, After
在.service
.但我的设备服务器不返回代码。设备服务器被调用后永远不会返回。我想知道如何告诉 systemd DeviceServer 现已设置完毕并且可以由其他服务使用。
我想,我可以在安装完成后分叉并作为父亲返回。然后这个孩子就会被领养。但是,那么我可以尽量不使用service reload
等。
那么如何让DeviceServer返回一个code并保持运行。
感谢帮助!
答案1
这里通常的答案是Type=notify
使用以下方式实现服务sd-notify
。这意味着当您启动一个服务时,它将保持该activating
状态,直到进程“通知”systemd 它已准备好。当该通知发生时,服务进入该active
状态。
[Service]
单元文件的部分应包含:
[Service]
Type=notify
ExecStart=webserver
然后将类似的代码添加到您的网络服务器:
#include <systemd/sd-daemon.h>
#include <unistd.h>
int main(void) {
/* Sleep to emulate 10s bootup time */
/* Expect status 'activating (start)' during this */
/* `systemctl start`, will block */
sleep(10);
/* Send a signal to say we've started */
sd_notify(0, "READY=1");
/* Units which are After= this unit will now start */
/* `systemctl start` will unblock now */
/* Sleep to emulate 10s run time */
/* Expect status 'active (running)' during this */
sleep(10);
/* Send a signal to say we've started the shutdown procedure */
sd_notify(0, "STOPPING=1");
/* Sleep to emulate 10s shutdown */
/* Expect status 'deactivating' during this */
sleep(10);
return 0;
/* Expect status 'inactive (dead)' at this point */
}
这远远优于简单的ExecStartPre=/bin/sleep 60
依赖服务,因为它是根据实际事件触发的。如果您的服务提前准备好,您的家属将尽快启动。如果在 60 秒内还没有准备好,您的家属将根据需要等待。
如果您不是该应用程序的开发人员,则需要弄清楚该应用程序如何向外界发出它已准备就绪的信号。也许它会记录到一个文件,或者您可能会继续对其使用 wget 直到它返回一些有意义的内容。在这种情况下,您可能希望创建一个与 MySqlServer 同时启动的观察程序服务。然后根据可用的任何信息处理通知。在这种情况下,DeviceServer 将依赖于您的观看服务而不是 MySqlServer。