让 systemd 用户服务等待 mysqld 在启动时可用的优雅方法

让 systemd 用户服务等待 mysqld 在启动时可用的优雅方法

我有一台服务器,我在该服务器上以普通用户身份运行守护程序。我打算将来向我信任的人授予对该用户的访问权限...但是,作为预防措施,我希望在没有 su 或 sudo 访问权限的情况下完成任何配置和管理。为此,我编写了一个简单的 systemd 用户单元并测试了它的工作原理。确实如此。

问题出在重新启动服务器时。 systemd 会尝试在 mariadb(该守护进程需要的)准备就绪之前启动该守护进程。这会导致守护进程反复失败,直到超过 systemd 的 StartLimit 并且 systemd 停止尝试一起启动守护进程。

我可以采取多种方法来解决这个问题。我可以重写 systemd 单元来运行一个脚本,该脚本一遍又一遍地查询 sql 服务器,直到它获得连接,然后才尝试启动守护进程。或者我可以在 systemd 单元中添加重新启动之间的超时时间,比如……30 秒?但两者都给人一种……混乱……平淡的感觉。我宁愿有一个更优雅的解决方案。

我一直在查看 systemd 的联机帮助页,但是......那里有很多内容。有什么想法吗?

有问题的单元文件:

[Unit]
Description=Teamspeak 3

[Service]
Type=forking
#User=teamspeak
#Group=teamspeak
UMask=0027
Restart=always
WorkingDirectory=/home/teamspeak/ts
PIDFile=/home/teamspeak/ts/ts3server.pid
ExecStart=/home/teamspeak/ts/ts3server_startscript.sh start inifile=/home/teamspeak/ts/ts3server.ini
ExecStop=/home/teamspeak/ts/ts3server_startscript.sh stop
ExecReload=/home/teamspeak/ts/ts3server_startscript.sh restart

[Install]
WantedBy=default.target

答案1

一种优雅的解决方案是使用套接字激活来启动系统服务,因为套接字激活的要点之一是允许启动相互依赖的服务,而无需显式指定它们的依赖关系(这反过来又允许它们的启动进一步并行化) .)

例如,参见这篇关于套接字激活的博客文章这非常清楚地表明了这一点:

套接字激活使得可以完全同时启动所有四个服务,而无需任何顺序。由于侦听套接字的创建已移至守护进程本身之外,因此我们可以同时启动它们,并且它们能够立即连接到彼此的套接字。

即使您的具体情况是用户单元和系统单元之间的交叉依赖,也适用相同的逻辑。

不幸的是,目前 MariaDB 似乎本身不支持系统激活。但您可以使用代理,例如systemd-socket-proxyd(8)在单独的端口上创建一个套接字激活的服务代理到 MariaDB。看这个问题更多细节。


另一种选择是将 Teamspeak 服务作为系统服务而不是用户服务,然后使用该User=指令(如您当前评论的那样)仍然与您的服务用户一起运行它。

既然您甚至将其描述为“守护进程”,我想说将其设为系统服务是完全合适的,甚至可能是更正确的方法。

存在缺点,例如使以“teamspeak”用户身份登录的人更难管理(停止/重新启动)服务,但我建议涉及切换到服务帐户的安排也有缺点(我个人认为避免这种设置),您仍然可以保留此设置并允许用户使用“sudo”或类似的方式管理系统服务。

答案2

Requires=mysqld.serviceWants=mysqld.service指令将帮助您的服务依赖。

systemd:单元依赖性和顺序有关详细信息,请参阅 fedora 杂志。

相关内容