SystemD에서 지정된 시간 후에 서비스를 시작하는 방법은 무엇입니까?

SystemD에서 지정된 시간 후에 서비스를 시작하는 방법은 무엇입니까?

SysV init 스크립트를 systemd로 변환하려고 합니다. SysV 구성은 다음과 같은 방식으로 다양한 프로세스를 생성합니다.

su -l $USER_A -c "$CMD_A &"
usleep 600000
su -l $USER_B -c "$CMD_B &"
usleep 100000
su -l $USER_C -c "$CMD_C &"
usleep 300000

모든 빌드 프로세스는 서로 다른 사용자를 사용하기 때문에 항상 각 프로세스에 대해 시스템 서비스 단위를 만들었습니다. 이 서비스 단위에서는 종속성을 지정합니다(Requires+After 사용). 예를 들어 서비스 단위 중 하나는 다음과 같습니다.

[Unit]
Description=CMD_B
Requires=CMD_A
After=CMD_A

[Service]
User=USER_B
Type=simple
ExecStart=/FULLPATH/CMD_B

[Install]
WantedBy=multi-user.target

문제는 다양한 프로세스가 POSIX 대기열을 통해 통신하고 이러한 대기열이 즉시 생성되지 않으므로 POSIX 대기열이 생성될 때까지 기다릴 만큼 강력하지 않기 때문에 각 시작 사이에 시간이 걸리고 실패한다는 것입니다.

이러한 프로세스는 변경할 수 없으므로 각 서비스 시작 사이의 경과 시간만 추가할 수 있습니다.

각 서비스 활성화 사이에 특정 기간을 고려해야 함을 systemd에 "명확하게" 알릴 수 있는 방법은 무엇입니까?

참고: systemd는 "이후" 종속성을 존중하지만 이러한 명령은 즉시 활성화되는 것으로 간주하므로 거의 동시에(몇 밀리초 이내에) 생성됩니다. 하나를 추가하려고 하면 ExecStartPost=/usr/bin/usleep 600000몇 밀리초 내에 생성되는 것처럼 보이며 서비스 유형이 단순하기 때문에 이것이 ExecStartPost결코 트리거되지 않을 것 같습니다. 그래서 시도했지만 ExecStartPre=/usr/bin/usleep 600000(CMD_C의 경우 CMD_C를 100000으로 변경했습니다) 이제 순서가 더 이상 존중되지 않는 것 같습니다. CMD_A가 먼저 시작된 다음 100ms 후에 CMD_C, 마지막으로 600ms 후에 CMD_B가 시작됩니다. 따라서 CMD_C는 CMD_B보다 먼저 시작되므로 실패합니다. 지금은 이 트릭을 사용했지만 ExecStartPre=CMD_B에는 600밀리초, CMD_C에는 700밀리초 등을 선택했습니다. 그것은 효과가 있지만 매우 나쁘다고 생각합니다.

답변1

타임아웃을 사용하지 않고 대신에 의존하는 방법을 생각해내고 싶습니다.파일을 기다리는 systemd의 메커니즘프로그램을 시작하기 전에 존재합니다.

아시다시피 Linux는 posix 메시지 대기열을 파일로 노출할 수 있습니다. 내 Fedora 시스템에서는 기본적으로 에서 이 작업을 수행하지만 /dev/mqueue/해당 디렉터리가 없으면 만들 수 있습니다.mount -t mqueue none /dev/mqueue

man systemd.path그런 다음 다음과 같은 간단한 단위를 사용할 수 있습니다(참조 ) myqueueb.path.

[Path]
PathExists=/dev/mqueue/queueb
[Install]
WantedBy=multi-user.target

그리고 또 다른myqueueb.service 같은 이름(또는 Unit=위에서 설정)

[Unit]
Description=CMD_B
[Service]
User=USER_B
Type=simple
ExecStart=/FULLPATH/CMD_B

당신이 원하는 것을하십시오. 하다두 번째 장치를 활성화하지 마십시오., 하지만 그렇게 systemctl enable myqueueb.path하고 systemctl start myqueueb.path. 그러면 파일에 inotifywait가 설정됩니다 /dev/mqueue/queueb.

이 파일은 첫 번째 프로그램이 메시지 큐를 생성할 때 queueb나타나며 systemd는 자동으로 myqueueb.service프로그램을 시작하고 실행합니다 CMD_B. 물론 대기열 이름과 CMD_C 간의 관계와 일치하도록 이러한 이름도 변경해야 합니다.

관련 정보