나는 다음과 같은 단위를 가지고 있습니다 :
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
testservice.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)에 나열된 스크립트를 실행한 다음, 출력.txt라는 텍스트 파일을 생성하여 소켓에 액세스되었습니다.
이는 예상대로 작동합니다(즉, 소켓에 액세스할 때 출력.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 ***************".
❯ 에코 "안녕하세요" Netcat 127.0.0.1 9991
❯ls
output.txt testservice.sh
❯ sudo systemctl 상태 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.