使用systemd创建Linux服务
在编写Web应用程序时,我经常需要将计算繁重的任务卸载到异步工作程序脚本,为以后安排任务,甚至编写一个侦听套接字以直接与客户端通信的守护程序。
虽然有时可能会有更好的工具 - 总是先考虑使用现有软件,例如任务队列服务器 - 编写自己的服务可以为您提供一定程度的灵活性,当您受到第三方约束的约束时软件。
很酷的是,创建Linux服务相当容易:使用您喜欢的编程语言编写一个长期运行的程序,并使用systemd将其转换为服务。
程序
让我们用PHP创建一个小型服务器。我可以看到你的眉毛上升,但效果出奇的好。我们将收听UDP端口10000,并通过ROT13返回转换收到的任何消息:
<?php
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($sock, '0.0.0.0', 10000);
for (;;) {
socket_recvfrom($sock, $message, 1024, 0, $ip, $port);
$reply = str_rot13($message);
socket_sendto($sock, $reply, strlen($reply), 0, $ip, $port);
}
让我们开始吧:
$ php server.php
并在另一个终端测试它:
$ nc -u 127.0.0.1 10000
Hello, world!
Uryyb, jbeyq!
很酷,很有效。现在我们希望此脚本始终运行,在发生故障(意外退出)时重新启动,甚至可以在服务器重新启动后继续运行。这就是systemd发挥作用的地方。
把它变成一项服务
让我们创建一个名为的文件/etc/systemd/system/rot13.service
:
[Unit]
Description=ROT13 demo service
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=centos
ExecStart=/usr/bin/env php /path/to/server.php
[Install]
WantedBy=multi-user.target
你需要:
- 之后设置您的实际用户名
User=
- 设置脚本的正确路径
ExecStart=
而已。我们现在可以开始服务了:
$ systemctl start rot13
并自动启动它开始启动:
$ systemctl enable rot13
走得更远
既然您的服务(希望如此)有效,那么深入了解配置选项并确保它始终按预期工作可能很重要。
从正确的顺序开始
您可能想知道该After=
指令的作用。它只是意味着必须在网络准备好后启动您的服务。如果您的程序希望MySQL服务器启动并运行,您应该添加:
After=mysqld.service
退出时重新启动
默认情况下,如果程序因任何原因退出,systemd不会重新启动您的服务。对于必须始终可用的服务,这通常不是您想要的,因此我们指示它始终在退出时重新启动:
Restart=always
如果退出状态不为0,还可以使用on-failure
重启。
默认情况下,systemd会在100ms后尝试重新启动。您可以使用以下命令指定在尝试重新启动之前等待的秒数:
RestartSec=1
避免陷阱:起始限制
我个人不止一次陷入这个问题。默认情况下,当您Restart=always
按照我们的方式进行配置时,如果在10秒间隔内未能启动超过5次,则systemd会放弃重新启动您的服务。永远。
有两个[Unit]
配置选项负责:
StartLimitBurst=5
StartLimitIntervalSec=10
该RestartSec
指令还会对结果产生影响:如果将其设置为在3秒后重新启动,那么您将永远无法在10秒内完成5次重试失败。
总是有效的简单修复是设置**StartLimitIntervalSec=0**
。这样,systemd将尝试永久重启您的服务。
设置RestartSec
为至少1秒是个好主意,以避免在出现问题时对服务器施加太大压力。
作为替代方案,您可以保留默认设置,并在达到启动限制时请求systemd重新启动服务器,使用StartLimitAction=reboot
。
那是真的吗?
这就是使用systemd创建Linux服务所需的全部内容:编写一个引用长期运行程序的小配置文件。
几年来,Systemd一直是RHEL / CentOS,Fedora,Ubuntu,Debian等中的默认初始化系统,因此很可能您的服务器已准备好托管您的自制服务!
翻译自:https://medium.com/@benmorel/creating-a-linux-service-with-systemd-611b5c8b91d6