서비스 초기화가 완료되고 완전히 실행되어 다른 서비스를 사용할 준비가 된 후에만 시작할 수 있는 여러 서비스(예 C0
: C1
... )가 있습니다. systemd를 사용하여 이를 어떻게 예약합니까?C9
S
존재하다systemd에서 경로 활성화 및 대상 순서 지정 서비스 사용서비스에 S
일종의 플래그 파일을 작성하는 메커니즘이 있다고 가정합니다. 대신, S
서비스가 실행되는 프로그램을 완전히 제어할 수 있고 필요한 경우 시스템 메커니즘을 추가할 수 있다고 가정해 보겠습니다 .
답변1
반드시 필요한 것은 아닙니다.
C
서비스가 소켓 연결을 열 준비가 될 때까지 기다려야 하는 경우에는 S
이 작업을 전혀 수행할 필요가 없습니다. 대신에 다음을 사용할 수 있습니다.조기 청취 소켓 열기서비스 관리자별.
다음을 포함한 여러 시스템로랑 벨코테의 S6,나의 간식 도구 세트systemd에는 몇 가지 방법이 있습니다청취 소켓서비스를 설정할 때 가장 먼저 해야 할 일인 만큼 최대한 빨리 오픈하는 것이 가능합니다. 이들 모두는 청취 소켓을 여는 서비스 프로그램과 호출 시 열린 파일 설명자로 청취 소켓을 수신하는 서비스 프로그램 이외의 다른 것을 포함합니다.
특히 systemd를 사용하여소켓 유닛청취 소켓을 정의합니다. systemd는 소켓 장치를 열고 커널 네트워킹 하위 시스템이 연결을 수신하도록 설정하고 소켓 연결을 처리하는 프로세스를 생성할 때 이를 열린 파일 설명자로 실제 서비스에 전달합니다. (이를 두 가지 방법으로 수행할 수 있지만 inetd
서비스와 서비스 세부 사항에 대한 논의는 이 답변의 범위를 벗어납니다.)Accept=true
Accept=false
중요한 점은 사람들이 반드시 이보다 더 많이 주문할 필요는 없다는 것입니다. 커널은 서비스 프로그램이 초기화되어 클라이언트 연결을 수락하고 클라이언트와 통신할 준비가 될 때까지 클라이언트 연결을 대기열에 일괄 처리합니다.
그렇게 하려면 프로토콜을 준비하는 것이 중요합니다.
systemd에는 다음과 같은 세트가 있습니다.계약 준비Type=
서비스는 서비스 단위의 설정을 통해 지정된다는 것을 이해합니다 . 여기서 관심 있는 특정 준비 프로토콜은 notify
준비 프로토콜입니다. 이를 통해 systemd는 서비스의 메시지를 기다리라는 지시를 받고 서비스가 준비되면 준비 완료라는 메시지를 보냅니다. systemd는 준비가 완료될 때까지 다른 서비스의 활성화를 지연합니다.
이를 악용하려면 다음 두 가지가 필요합니다.
S
Pierre-Yves Ritschardnotify_systemd()
함수 또는 Cameron T Norman 함수notify_socket()
와 같은 함수를 호출하도록 코드를 수정합니다 .Type=notify
서비스에 대한 서비스 단위를 사용하고 설정합니다NotifyAccess=main
.
이 NotifyAccess=main
제한(기본값)은 시스템의 모든 프로세스가 systemd의 알림 소켓에 메시지를 보낼 수 있기 때문에 systemd가 장난스러운(또는 단순한 버그가 있는) 프로그램의 메시지를 무시해야 한다는 것을 알아야 하기 때문입니다.
사람들은 Pierre-Yves Ritchard 또는 Cameron T Norman의 코드를 선호합니다. 왜냐하면 UbuntuBSD, Debian FreeBSD, 실제 FreeBSD, TrueOS, OpenBSD 등에서 이 메커니즘을 사용할 가능성을 배제하지 않기 때문입니다. systemd 작성자가 제공한 코드는 이를 제외합니다.
피해야 할 함정 중 하나는 systemd-notify
프로그래밍입니다. 여기에는 몇 가지 주요 문제가 있으며, 그 중 가장 중요한 것은 함께 전송된 메시지가 systemd에서 처리되지 않고 폐기될 수 있다는 것입니다. 이 경우 S
가장 큰 문제 는 서비스의 "주" 프로세스로 실행되지 않으므로 이를 사용해야 한다는 것입니다 NotifyAccess=all
.
피해야 할 또 다른 함정은 forking
합의가 더 간단하다고 생각하는 것입니다. 그렇지 않습니다. 행위바르게프로그램의 모든 작업자 스레드가 실행될 때까지 상위 스레드를 분기하거나 종료하지 않는 것과 관련됩니다. 이는 대다수의 포크 데몬이 실제로 포크하는 방식과 일치하지 않습니다.
추가 읽기
- 조나단 데보인 폴라드(2015).Unix 데몬의 준비 프로토콜 문제. 자주 주어지는 답변입니다.
- 레나르트 페틀링(2010).
sd_notify()
. 시스템 매뉴얼 페이지. freedesktop.org. - 레나르트 페틀링(2010).
systemd-notify
. 시스템 매뉴얼 페이지. freedesktop.org. - 특정 인터페이스가 시작되기 전에 시작될 때까지 기다리도록 시스템 서비스 단위 파일을 작성하려면 어떻게 해야 합니까?
- systemd의 상태 출력에 상태 정보 추가
답변2
이와 같이:
제공하다
[Unit]
Description=My main Service
[Service]
Type=notify
ExecStart=/usr/bin/myBinary
C0 서비스
[Unit]
Description=Dependent service number 0
PartOf=S.service
C1.서비스
[Unit]
Description=Dependent service number 1
PartOf=S.service
C9.서비스
[Unit]
Description=Dependent service number 9
PartOf=S.service
/usr/bin/myBinary가 사용하는 곳sd_notify 준비=1초기화가 완료된 후 호출됩니다.
종속성 동작 방식에 따라 PartOf, Requires 또는 BindsTo를 사용할 수 있습니다.다른 사람.
답변3
systemd.service(5)
매뉴얼 페이지에 대한 구체적인 참조유형에 관한 부분에 대해 =각 서비스 유형에는 Systemd가 다른 서비스에 기능을 제공할 준비가 되었는지 확인하는 방법이 다릅니다.
그렇다면
Type=simple
데몬이 시작되기 전에 해당 통신 채널을 설치해야 합니다(예: 소켓 활성화를 통해 systemd에 의해 설정된 소켓).이면
Type=forking
시작이 완료되고 모든 통신 채널이 설정된 후 상위 프로세스가 종료될 것으로 예상됩니다.그렇다면
Type=dbus
데몬은 D-Bus 버스에서 이름을 얻을 것으로 예상되며, 이 시점에서 systemd는 후속 장치를 시작합니다.이면
Type=notify
데몬은sd_notify(3)
시작이 완료될 때 또는 동등한 호출을 통해 알림 메시지를 보낼 것으로 예상됩니다. 이 알림 메시지를 보낸 후 systemd는 후속 장치를 시작합니다.
마지막 옵션(메시지 전송 sd_notify
)의 경우 유틸리티를 사용할 수 systemd-notify
있으며 를 사용하여 액세스 권한을 부여하는 것을 기억하세요 NotifyAccess=all
.
귀하가 서비스를 제어할 수 있다면 S
귀하의 사용 사례에 가장 적합한 옵션을 선택하거나 구현하기 가장 쉬운 옵션을 자유롭게 선택할 수 있습니다.