我有以下单位:
test_socket_activation.socket
[Unit]
Description="************** MY TEST SOCKET ***************"
PartOf=test_socket_activation.service
[Socket]
ListenStream=127.0.0.1:9991
[Install]
WantedBy=sockets.target
test_socket_activation.service
[Unit]
Description="********** MY TEST SERVICE *****************"
[Service]
ExecStart=/home/xxx/sysadmin/systemd_units/socket_based_activation/testservice.sh
[Install]
WantedBy=multi-user.target
测试服务.sh
#!/bin/bash
echo "Socket Service Triggered" > output.txt
理论上,systemd 应该监听 127.0.0.1 端口 9991(通过 test_scocket_activation.socket)。当访问套接字时,systemd 应该调用父单元 (test_scocket_activation.service),而父单元又应该执行 ExecStart 指令 (testservice.sh) 中列出的脚本,然后创建一个名为 output.txt 的文本文件来通知套接字已被访问。
这按预期工作(即访问套接字时创建了output.txt),除了服务单元(test_scocket_activation.service)随后由于“启动请求重复太快,拒绝启动”而失败,即使套接字仅被访问一次。然后,服务的故障会触发关联套接字的故障,从而停止侦听。
我在这里做了一些测试,这是我的步骤和日志输出:
❯ sudo systemctl start test_socket_activation.socket
❯ sudo systemctl 状态 test_socket_activation.socket
● test_socket_activation.socket - "************** MY TEST SOCKET ***************"
Loaded: loaded (/etc/systemd/system/test_socket_activation.socket; disabled)
Active: active (listening) since Thu 2020-03-19 14:08:40 +01; 17s ago
Listen: 127.0.0.1:9991 (Stream)
Mar 19 14:08:40 toshi systemd[1]: Starting "************** MY TEST SOCKET ***************".
Mar 19 14:08:40 toshi systemd[1]: Listening on "************** MY TEST SOCKET ***************".
❯ 回显“你好” |网猫 127.0.0.1 9991
❯ ls
output.txt testservice.sh
❯ sudo systemctl status test_socket_activation.service
● test_socket_activation.service - "********** MY TEST SERVICE *****************"
Loaded: loaded (/etc/systemd/system/test_socket_activation.service; disabled)
Active: failed (Result: start-limit) since Thu 2020-03-19 14:10:42 +01; 9min ago
Process: 2842 ExecStart=/home/mkr/sysadmin/systemd_units/socket_based_activation/testservice.sh (code=exited, status=0/SUCCESS)
Main PID: 2842 (code=exited, status=0/SUCCESS)
Mar 19 14:10:42 toshi systemd[1]: Started "********** MY TEST SERVICE *****************".
Mar 19 14:10:42 toshi systemd[1]: Starting "********** MY TEST SERVICE *****************"...
Mar 19 14:10:42 toshi systemd[1]: test_socket_activation.service start request repeated too quickly, refusing to start.
Mar 19 14:10:42 toshi systemd[1]: Failed to start "********** MY TEST SERVICE *****************".
Mar 19 14:10:42 toshi systemd[1]: Unit test_socket_activation.service entered failed state.
❯ sudo systemctl 状态 test_socket_activation.socket
● test_socket_activation.socket - "************** MY TEST SOCKET ***************"
Loaded: loaded (/etc/systemd/system/test_socket_activation.socket; disabled)
Active: failed (Result: service-failed-permanent) since Thu 2020-03-19 14:10:42 +01; 41s ago
Listen: 127.0.0.1:9991 (Stream)
Mar 19 14:08:40 toshi systemd[1]: Starting "************** MY TEST SOCKET ***************".
Mar 19 14:08:40 toshi systemd[1]: Listening on "************** MY TEST SOCKET ***************".
Mar 19 14:10:42 toshi systemd[1]: Unit test_socket_activation.socket entered failed state.
❯ sudo Journalctl -u test_socket_activation.service
-- Logs begin at Thu 2020-03-19 14:05:23 +01, end at Thu 2020-03-19 14:17:29 +01. --
Mar 19 14:10:42 toshi systemd[1]: Starting "********** MY TEST SERVICE *****************"...
Mar 19 14:10:42 toshi systemd[1]: Started "********** MY TEST SERVICE *****************".
Mar 19 14:10:42 toshi systemd[1]: Starting "********** MY TEST SERVICE *****************"...
Mar 19 14:10:42 toshi systemd[1]: Started "********** MY TEST SERVICE *****************".
Mar 19 14:10:42 toshi systemd[1]: Starting "********** MY TEST SERVICE *****************"...
Mar 19 14:10:42 toshi systemd[1]: Started "********** MY TEST SERVICE *****************".
Mar 19 14:10:42 toshi systemd[1]: Starting "********** MY TEST SERVICE *****************"...
Mar 19 14:10:42 toshi systemd[1]: Started "********** MY TEST SERVICE *****************".
Mar 19 14:10:42 toshi systemd[1]: Starting "********** MY TEST SERVICE *****************"...
Mar 19 14:10:42 toshi systemd[1]: Started "********** MY TEST SERVICE *****************".
Mar 19 14:10:42 toshi systemd[1]: Starting "********** MY TEST SERVICE *****************"...
Mar 19 14:10:42 toshi systemd[1]: test_socket_activation.service start request repeated too quickly, refusing to start.
Mar 19 14:10:42 toshi systemd[1]: Failed to start "********** MY TEST SERVICE *****************".
Mar 19 14:10:42 toshi systemd[1]: Unit test_socket_activation.service entered failed state.
正如您在上面看到的,套接字仅被访问一次,服务被触发,并且它确实调用脚本来创建output.txt 文件。但不久后,服务因多次尝试启动而失败。
我的问题如下:
当套接字仅访问一次(通过 echo "hello" | netcat 127.0.0.1 9991)时,为什么服务启动多次?
当关联的套接字仅被访问一次时,如何避免服务多次启动?
所有答案/意见/见解将不胜感激,谢谢。
答案1
您已经创建了一个Accept=No
套接字,其中服务被传递了侦听套接字文件描述符,并且预计将接受连接,并且保持运行。赠品应该是您没有创建模板服务单元,而套接字则需要模板服务单元,Accept=Yes
其中服务传递连接的套接字文件描述符。
进一步阅读
- 乔纳森·德博因·波拉德 (2019)。
tcp-socket-accept
。 小吃指南。软件。 - https://unix.stackexchange.com/a/513663/5132
s6-tcpserver4d
。洛朗·贝尔科特. s6 网络。 skarnet.org。