
以下のユニットを所有しています:
テストソケットアクティベーションソケット
[Unit]
Description="************** MY TEST SOCKET ***************"
PartOf=test_socket_activation.service
[Socket]
ListenStream=127.0.0.1:9991
[Install]
WantedBy=sockets.target
テストソケットアクティベーションサービス
[Unit]
Description="********** MY TEST SERVICE *****************"
[Service]
ExecStart=/home/xxx/sysadmin/systemd_units/socket_based_activation/testservice.sh
[Install]
WantedBy=multi-user.target
テストサービス
#!/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 が作成されます)。ただし、ソケットが 1 回しかアクセスされていないにもかかわらず、サービス ユニット (test_scocket_activation.service) は「開始要求があまりにも速く繰り返されたため、開始を拒否しました」という理由でその後失敗します。サービスの失敗により、関連するソケットの失敗がトリガーされ、リスニングが停止します。
いくつかテストを行いました。手順とログ出力は次のとおりです。
❯ sudo systemctl start test_socket_activation.socket
❯ sudo systemctl status 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 status 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.
上記のように、ソケットは 1 回だけアクセスされ、サービスがトリガーされ、スクリプトを呼び出して output.txt ファイルを作成します。しかし、その直後に、サービスは複数回起動を試行して失敗します。
私の質問は次のとおりです。
ソケットは 1 回しかアクセスされていないのに (echo "hello" | netcat 127.0.0.1 9991 経由)、サービスが複数回起動するのはなぜですか?
関連するソケットに一度だけアクセスした場合に、サービスが複数回起動しないようにするにはどうすればよいですか?
すべての回答/入力/洞察をいただければ幸いです。ありがとうございます。
答え1
ソケットを作成しAccept=No
、サービスにリスニングソケットファイル記述子が渡され、接続の受け入れを行うことが期待されます。走り続けるAccept=Yes
.サービスが接続されたソケット ファイル記述子を渡すソケットに必要なテンプレート サービス ユニットを作成していないことがわかります。
参考文献
- ジョナサン・デ・ボイン・ポラード(2019年)。
tcp-socket-accept
。 noshガイド. ソフトウェア。 - https://unix.stackexchange.com/a/513663/5132
s6-tcpserver4d
。ローラン・ベルコ。 s6-ネットワーキング。 skarnet.org をご覧ください。