systemd의 단순 유형 서비스에 대해 "프로세스가 분기되지 않아야"하는 이유는 무엇입니까?
systemd
정말 오래 실행되는 명령 1 (시간 단위) 을 관리하기 위해 고유 한 단위 파일 을 작성하고 싶습니다 . systemd에 대한 ArchWiki 기사를 보면서 시작 유형 선택과 관련하여 다음과 같이 말합니다.
Type=simple
(기본값) : systemd는 서비스가 즉시 시작되는 것으로 간주합니다. 프로세스가 분기되어서는 안됩니다 . 이 서비스에 대해 다른 서비스를 주문해야하는 경우 소켓이 활성화되지 않은 경우이 유형을 사용하지 마십시오.
프로세스가 전혀 분기되지 않아야하는 이유는 무엇입니까? 데몬 소환 프로세스 (부모 포크 후 종료) 스타일의 포크를 의미합니까, 아니면 어떤 종류의 포크를 의미합니까?
1 tmux / screen에 의존하지 않고 상태를 확인하고 서비스를 다시 시작하는보다 우아한 방법을 원하기 때문에 tmux / screen을 원하지 않습니다 tmux send-keys
.
답변
서비스는 fork
시스템 호출 을 호출 할 수 있습니다. Systemd는 그것을 막지 못하거나, 막아도 알아 차리지 못합니다. 이 문장은 특히 데몬을 부모 프로세스에서 분리하기 위해 데몬 시작 부분에서 분기하는 방법을 나타냅니다. "프로세스는 [하위 프로세스에서 서비스를 실행하는 동안 부모를 종료하고] 분기해서는 안됩니다."
매뉴얼 페이지 더 자세하게이 설명하고이 특정 혼란으로 이어질하지 않는 표현하는.
데몬으로 사용되는 많은 프로그램에는 시작할 때 부모와 분리되는 모드 (종종 기본 모드)가 있습니다. 데몬이 시작되고을 호출 fork()
하고 부모가 종료됩니다. 하위 프로세스 setsid()
는 자체 프로세스 그룹 및 세션에서 실행되도록 호출 하고 서비스를 실행합니다. 목적은 데몬이 쉘 명령 줄에서 호출되는 경우, 데몬은 터미널 닫힘 (이 경우 쉘이 SIGHUP을 전송하는 경우)과 같은 터미널에 어떤 일이 발생하더라도 커널 또는 쉘로부터 신호를 수신하지 않습니다. 알고있는 모든 프로세스 그룹에). 이로 인해 서비스 프로세스가 init에 의해 채택되어 종료 될 때이를 거두어 데몬이 시작된 경우 좀비를 피할 wait()
수 있습니다 (데몬이 쉘에 의해 시작된 경우에는 발생하지 않음). ).
systemd와 같은 모니터링 프로세스에 의해 데몬이 시작되면 포크는 비생산적입니다. 모니터링 프로세스는 서비스가 충돌하면 서비스를 다시 시작해야하므로 서비스가 종료되는지 알아야하며 서비스가 모니터링 프로세스의 직접적인 자식이 아닌 경우에는 어렵습니다. 모니터링 프로세스는 절대 죽어서는 안되며 제어 터미널이 없기 때문에 원하지 않는 신호 나 수확에 대한 우려가 없습니다. 따라서 서비스 프로세스가 모니터의 자식이 아닐 이유가 없으며 그럴만한 이유도 있습니다.
이 아치 위키 페이지를 무시하십시오.
Type
설정 과 관련하여 상당히 잘못되었습니다 . simple
또한 에 대한 설명에만 국한되지 않습니다 . 그것에 대해 말하는 forking
것도 잘못되었습니다.
이러한 종류의 올바른 권장 사항은 시스템 자체가 존재했던 것보다 수십 년 동안 존재했으며 적어도 1990 년대 초로 거슬러 올라갑니다. 내가 언급했듯이https://unix.stackexchange.com/a/476608/5132, systemd doco에는 daemontools 사용자, IBM, 사용하는 사람들 inittab
, 그리고… 음… 수십 년 동안 말한 내용을 대체로 반복하는 dæmons에 대한 권장 사항의 Johnny-come 최신 버전이 있습니다. (이미 2001 년에 이렇게 적었을 때 자주 주어진 대답이었습니다.)
반복하려면 :
프로그램이 일부 "dæmonization"메커니즘이있는 경우, 그 특정 포크의 아동과 종료 부모 프로세스는, 그것을 해제 하고 사용하지 마십시오 . daemontools 외 덕분에. 이것이 오랫동안 요구되었던 곳에서, 많은 프로그램은 지난 20 년 동안 그러한 메커니즘을 갖지 않는 능력을 키웠고, 다른 프로그램은 단순히 처음에 "악화"를 기본으로하지 않기 때문에 다음에서 사용할 수 있습니다. 기본 작동 모드.
서비스 관리 서브 시스템은 이미 dæmon 컨텍스트에서 서비스 프로세스 를 시작합니다 . 이러한 프로세스는 "dæmonize"할 필요가 없습니다. (실제로, 프로그램 이 로그인 세션 컨텍스트에서 "데모 니화" 할 수 있다고 생각하는 것은 많은 현대 운영 체제의 오류입니다 . 이는 "데모 니 제이션"이 실제로 의미하는 것입니다.) 그들은 이미 환경 값과 열린 파일 설명자를 가지고 있습니다. 데몬 상황에 적절한, 그리고 사실 "dæmonization"에 의해 수행 된 몇 가지 방해 정기적으로 서비스 매니저 (로그에 예를 들어 캡처 자신의 표준 출력 / 오류) 데몬으로 수행하고있는 기존의 몇 가지.
선호 Type=simple
, 조기 소켓 열기 (서비스 관리가 서버 소켓을 열고 이미 열린 파일 설명 자로 서비스 프로그램에 전달) 또는 Type=notify
.
Type=simple
서비스 프로세스가 시작 되 자마자 서비스를 준비된 것으로 처리합니다 (주문 된 서비스가 시작 / 중지 될 수 있도록). 초기 소켓 열기는 소켓 연결 의미 체계를 사용하여 서비스 클라이언트가 서버에 연결을 시도하는 지점에서 지연합니다. 서비스, 서버가 실제로 준비 될 때까지.Type=notify
systemd 및 Linux에 특유한 단점이 있습니다 (셸 생성과 같은 단기 프로세스에서 작동하지 않는 문제systemd-notify
와 권한이 부여 된 프로세스에서 사람이 읽을 수있는 형식을 기계가 읽을 수있는 형식으로 파싱 하는 문제와 함께 ). 파서 문제는 이미 과거에 발생 했지만 서비스 프로그램의 관점에서 보면 서비스가 실제로 준비된 것으로 간주되는시기를보다 세밀하게 제어 할 수있는 이점이 있습니다. 또한 상태 출력을 일부 사용자 정의 할 수 있습니다.
두 유형의 서비스 프로그램은 포크 할 수 있습니다. 문제인 원래 프로세스 를 분기 하고 종료합니다 .
(이는 서비스 관리자에서 프로그램을 실행하는 것만큼이나 쉘에서 프로그램을 실행하는 데 문제가된다는 점에 유의해야합니다. 사용자는 프로그램이 종료되고 거의 즉시 다른 쉘 프롬프트가 발생하는 것을 볼 수 있습니다. 실제로 오늘 누군가가 다시 묻고있었습니다. , 부모를 포크하고 종료하는 셸에서 프로그램을 실행하는 방법에 대해, 왜 가끔 터미널에서 프로그램을 실행할 때 터미널에서 실행되지 않습니까? .)
Type=oneshot
전체 서비스 프로그램이 완료 될 때만 서비스가 준비된 것으로 간주되기 때문에이 특정 경우에는 원하는 것이 아닐 수 있습니다. 그것은 그것의 용도가 있지만 그것의 소리로 그들은 당신에게 적용되지 않습니다.
사용하지 마십시오 Type=forking
. 실제로 프로토콜을 사용하는 프로그램은 거의 없기 때문에 절망의 최후의 수단이되어야 합니다 . 그들은 실제로이 프로토콜이 아니고, 이 프로토콜과 올바르게 상호 운용되지 않으며, 실제로 신호 준비 상태 가 아닌 다른 작업을 하고 있습니다 .
추가 읽기
- 조나단 드 보인 폴라드 (2001). Unix dæmon 프로그램을 설계 할 때 피해야 할 실수 . 자주 제공되는 답변.
- 조나단 드 보인 폴라드 (2015). 정말 데몬화할 필요가 없습니다. 정말. . 체계적인 공포의 집.
- 조나단 드 보인 폴라드 (2015). Unix dæmons의 준비 프로토콜 문제 . 자주 제공되는 답변.
- https://unix.stackexchange.com/a/401611/5132