Systemd는 After= 의존성을 존중하지 않는 것 같나요?

Systemd는 After= 의존성을 존중하지 않는 것 같나요?

저는 PostgreSQL 서버( postgresql.service)와 기본 셸 스크립트( mobilizon-postgresql.service데이터베이스에 대한 일부 어설션을 세 번째 서비스(Mobilizon)에 제공하기 위해 실행됩니다.

따라서 당연히 다음 에 대한 종속성 mobilizon-postgresql.service으로 구성됩니다 .After=postgresql.service

# systemctl show mobilizon-postgresql.service | grep After=
After=basic.target system.slice systemd-journald.socket sysinit.target postgresql.service

(이러한 종속성을 건드리지 않은) 시스템을 재구성한 후에도 로그에 다음 동작이 표시됩니다.

1677672119.103035 myserver systemd[1]: Starting Mobilizon PostgreSQL setup...
...
1677672119.153192 myserver systemd[1]: Starting PostgreSQL Server...

그래서 mobilizon-postgresql.service시작되었습니다~ 전에의 시작 postgresql.service.

1677672119.279742 myserver mobilizon-postgresql-start[329444]: psql: error: could not connect to server: No such file or directory
1677672119.279742 myserver mobilizon-postgresql-start[329444]:         Is the server running locally and accepting
1677672119.279742 myserver mobilizon-postgresql-start[329444]:         connections on Unix domain socket "/run/postgresql/.s.PGSQL.543>
1677672119.283558 myserver systemd[1]: mobilizon-postgresql.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
1677672119.283707 myserver systemd[1]: mobilizon-postgresql.service: Failed with result 'exit-code'.
1677672119.289678 myserver systemd[1]: Failed to start Mobilizon PostgreSQL setup.

물론 mobilizon.postgresqlDB에 대한 연결을 설정할 수 없습니다.

1677672119.503881 myserver postgres[329458]: [329458] LOG:  starting PostgreSQL 13.10 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 11>
1677672119.512541 myserver postgres[329458]: [329458] LOG:  listening on IPv4 address "0.0.0.0", port 5432
1677672119.512863 myserver postgres[329458]: [329458] LOG:  listening on IPv6 address "::", port 5432
1677672119.519498 myserver postgres[329458]: [329458] LOG:  listening on Unix socket "/run/postgresql/.s.PGSQL.5432"
...
1677672119.871989 myserver systemd[1]: Started PostgreSQL Server.

나중에야 postgresql.service완전히 시작되었다고 보고됩니다.

이 행동은 에 대한 나의 이해와 완전히 반대됩니다 After=. 에서 systemd.unit(5):

foo.service 장치에 Before=bar.service 설정이 포함되어 있고 두 장치가 모두 시작되고 있는 경우 foo.service의 시작이 완료될 때까지 bar.service의 시작이 지연됩니다.

여기에 잘못된 가정이 있습니까?

시스템 버전은 251.12, Distro는 NixOS 22.11입니다.

답변1

systemd는 "시작 완료"란 무엇을 의미합니까? man systemd.unit라고

서비스 단위의 경우 구성된 모든 시작 명령이 호출되고 실패했거나 시작 성공이 보고된 경우 Before=/After= 목적으로 시작이 완료된 것으로 간주됩니다.

따라서 postgresql 서비스 파일을 살펴보고 해당 서비스 파일이 포크하여 pid를 파일에 넣는지 또는 sd_notify()코드에서 "준비" 신호를 보내는 것과 같은 작업을 수행하는지 확인해야 합니다. 별로 유용하지 않습니다.

안타깝게도 이 문제를 해결하는 쉬운 방법은 서비스 mobilizon-postgresql 가 Unix 도메인 소켓이 존재할 때까지 기다리거나 inotifywait유사한 방법을 사용하거나 성공할 때까지 추가 Restart=on-failure하고 재시도하는 것입니다.RestartSec=1

작업 방식에 대한 Systemd의 아이디어는 소켓 장치를 생성하고 누군가가 해당 소켓을 열려고 할 때마다 프로그램을 시작하는 것입니다. 이 경우 소켓을 여는 스크립트를 시작하면 postgresql이 시작됩니다.

답변2

(전체 단위를 표시하는 것이 도움이 될 것입니다. 그런데)

After=a가 없거나 생각하는 효과 Wants=Requires=없습니다. 다음 과 같이 man systemd.unit설명합니다( Before=, After=).

참고하세요해당 설정은 요구 사항 종속성과 독립적이고 직교합니다.Requires=, Wants=, Requisite=또는 으로 구성됩니다 BindsTo=. After=및 옵션 모두에 장치 이름을 포함하는 것이 일반적인 패턴입니다 Wants=. 이 경우 나열된 장치는 이러한 옵션으로 구성된 장치보다 먼저 시작됩니다.

(포스터에서 강조 추가)

관련 정보