대상 소켓이 수신 대기 중인 *후*에만 systemd 서비스를 시작하시겠습니까?

대상 소켓이 수신 대기 중인 *후*에만 systemd 서비스를 시작하시겠습니까?

시작 시 청취 소켓에 연결해야 하는 서비스 X가 있습니다. 대상 소켓 자체는 systemd에 의해 시작된 다른 서비스 Y에 의해 열립니다.

서비스 Y가 성공적으로 시작되고 청취 소켓을 연 후에만 서비스 X가 시작되도록 단위 파일(또는 다른 수단)에 지정하는 방법이 있습니까?

초기 연결이 실패하면 재시도하도록 서비스 X를 변경할 수 없습니다. 또한 고정 지연은 서비스 Y가 청취 소켓을 열기 전에 다른 시간이 걸리기 때문에 제대로 작동하지 않습니다.

답변1

systemd는 약간 다르게 작동하는 경향이 있습니다. 소켓을 생성하고 수신하도록 systemd를 구성하고 X와 같은 사람이 연결을 시도하면 systemd는 Y를 시작하여 연결을 처리하고 소켓을 전달합니다. 따라서 명목상 X는 Y보다 먼저 시작할 수 있지만 그것은 중요하지 않습니다. 나중에 연결은 Y에 의해 처리됩니다. (각 연결마다 Y가 다시 시작되도록 구성할 수도 있지만 귀하의 경우는 아닌 것 같습니다.)

Y에 대한 최소한의 변경 사항은 자체적으로 생성/바인딩하는 대신 미리 생성된 소켓을 stdin/stdout 파일 설명자로 허용하도록 하는 것입니다.

이것은 루트로 시도하지 않고도 시도해 볼 수 있는 테스트 설정입니다. 3개의 유닛 파일이 필요합니다. ~/.local/share/systemd/user/mysock.socket소켓을 생성하고 전달하는 방법을 systemd에 지시합니다.

# create listening socket. on 1st connect run mysock.service
[Socket]
ListenStream=5555
Accept=false

~/.local/share/systemd/user/mysock.service(동일한 이름을 가짐 mysock)은 누구든지 소켓에 연결할 때 시작되는 서비스입니다. 여기가 Y를 시작하는 곳입니다. 저는 이를 Python으로 대체했습니다.

[Unit]
Description=started from mysock.socket
[Service]
ExecStart=/home/meuh/bin/python/mysock.py
StandardInput=socket

마지막으로 X 서비스에는 소켓이 필요함을 나타내는 단위가 있습니다. XI의 경우 socat을 사용하여 소켓에 날짜를 씁니다. ~/.local/share/systemd/user/mysockdepend.service

[Unit]
Description=dependent on socket listening
Requires=mysock.socket
[Service]
ExecStart=/usr/bin/socat -U tcp:localhost:5555 exec:/usr/bin/date

Python은 표준 입력(예: 파일 설명자 0)에서 소켓을 가져오고 이를 적합한 Python 소켓 객체로 래핑하고 작업을 수행하며 accept()읽기/쓰기가 가능합니다. ~/bin/python/mysock.py

#!/usr/bin/python
# started from /home/meuh/.local/share/systemd/user/mysock.service
# with socket on stdin/stdout
import sys, time, socket, subprocess

def debug(msg):
#    time.sleep(3)
    subprocess.call(["/usr/bin/logger", msg])

debug("start\n")
s = socket.fromfd(sys.stdin.fileno(), socket.AF_INET, socket.SOCK_STREAM)
while True:
    conn, addr = s.accept()
    conn.send("hello\n")
    while True:
        try:
            data = conn.recv(100)
            debug("got "+data+"\n")
            if len(data)<=0: break
        except:
            break
    conn.close()

그 후에 systemctl --user daemon-reload는 X를 실행할 수 있어야 합니다.

systemctl --user start mysockdepend

로그에서 journalctlY가 시작된 것을 확인하고 날짜와 함께 출력을 디버그하세요.

읽다소켓 활성화그리고2위그것을 발명한 사람으로부터.

답변2

systemd가 이 상황을 처리합니다.소켓 파일.

some-socket.socket소켓을 나타내기 위해 systemd라는 단위 파일이 생성됩니다 .

Service X그러면 서비스 파일에 소켓을 참조하는 지시문이 포함될 수 있습니다 After=.

소켓 파일에 대한 공식 시스템 문서가 도움이 될 것입니다.

관련 정보