ExecStop이 완료되기 전에 systemd가 내 프로세스를 종료합니다.

ExecStop이 완료되기 전에 systemd가 내 프로세스를 종료합니다.

systemd와 함께 사용하도록 애플리케이션을 업데이트하려고 합니다. Upstart를 사용할 때 방금/etc/init.d/myService스크립트:

#!/bin/bash
#chkconfig: 2345 90 10
#description: myDescription

### BEGIN INIT INFO
# Provides: myService
# Required-Start: sshd
# Required-Stop: sshd
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start myService
# Description:
### END INIT INFO

SCRIPT=$(readlink -f $0)
lockfile="/var/lock/subsys/myService"

do_start() {
    if [ -d "/var/lock/subsys" ]; then
        touch $lockfile
    fi
    ...
}

do_stop() {
    ...
    if [ -d "/var/lock/subsys" ]; then
        if [ -f "$lockfile" ]; then
            rm -f $lockfile
        fi
    fi
}

do_status() {
    ...
}


case "$1" in
  start)
    do_start
    exit 0
    ;;
  stop)
    do_stop
    exit 0
    ;;
  status)
    do_status
    exit 0
    ;;
  restart)
    do_stop
    do_start
    exit 0
    ;;
  *)
    echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
    exit 3
    ;;
esac

모두 괜찮습니다.

알아채다, 이 스크립트는 백그라운드에서 실행될 일부 하위 프로세스를 생성합니다. systemd와 함께 사용하기 위해 다음 서비스 파일(myService.service):

[Unit]
Description=My Description
Requires=sshd.service
After=sshd.service
Before=shutdown.target reboot.target halt.target

[Service]
Type=oneshot
ExecStart=/etc/init.d/myService start
ExecStop=/etc/init.d/myService stop
RemainAfterExit=yes
KillMode=none

[Install]
WantedBy=multi-user.target

내가 달리면

systemctl stop myService.service

모든 것이 잘 작동합니다. 내 응용 프로그램이 성공적으로 중지되었습니다./etc/init.d/myService 중지주문하다.

그런데 다음과 같은 문제가 발생했습니다. 시스템을 재부팅했을 때,/etc/init.d/myService 중지프로세스가 실행 중이므로 중지해야 합니다.내 서비스스크립트가 종료되었습니다. 나는 많은 프로세스(약 7개 프로세스)를 제어해야 하며 시스템이 스스로 프로세스를 종료해서는 안 됩니다.

Type=forking을 사용하고 수명이 가장 긴 프로세스의 pidfile로 PIDFile을 지정하려고 시도했지만(먼저 시작하고 마지막으로 중지해야 함) 모든 프로세스가 다시 종료됩니다.

내 자식 프로세스가 종료되는 것을 방지하는 쉬운 방법이 있습니까?

문제가 있으면 루트가 아닌 다른 사용자가 애플리케이션을 실행합니다.

답변1

해결책을 찾았습니다.

나는 hadoop과 hbase를 실행하고 있으며 해당 구성 요소 중 일부는 localhost에 대한 ssh 연결을 통해 시작되며 이러한 방식으로 시작된 프로세스는 systemd에서 제어할 수 없습니다. 이것은 분산 시스템 설계이지만 제 경우에는 하나의 시스템에서 작업이 수행됩니다. 그래서 나는 다음으로 교체했습니다.하둡/bin/slaves.sh

for slave in `cat "$HOSTLIST"|sed  "s/#.*$//;/^$/d"`; do
 ssh $HADOOP_SSH_OPTS $slave $"${@// /\\ }" \
   2>&1 | sed "s/^/$slave: /" &
 if [ "$HADOOP_SLAVE_SLEEP" != "" ]; then
   sleep $HADOOP_SLAVE_SLEEP
 fi
done

도착하다

for slave in `cat "$HOSTLIST"|sed  "s/#.*$//;/^$/d"`; do
eval "$@"
 if [ "$HADOOP_SLAVE_SLEEP" != "" ]; then
   sleep $HADOOP_SLAVE_SLEEP
 fi
done

문제가 해결되었으며 이제 프로세스가 서비스 프로세스 트리에 표시됩니다.

Hbase에는 동일한 솔루션이 있을 수 있지만 이제 distribution=false로 시작하고 ssh를 통해 어떤 프로세스도 시작하지 않습니다.

답변2

저도 같은/비슷한 문제가 있습니다. "myService" 스크립트 내에서 su 또는 sudo를 사용한다고 가정하겠습니다. 이로 인해 서비스 프로세스가 system.slice 대신 user.slice에서 시작됩니다.
분명히 user.slice에서 "중요한" 어떤 ​​것도 실행되어서는 안 되며, systemd는 종료/다시 시작 시 모든(?) 프로세스를 종료합니다.
시작 스크립트에서 모든 사용자 스위치(su/sudo)를 제거하고 유닛 파일에서 사용자 지시문(User=xxx)을 사용하여 이 문제를 해결했습니다.

프로세스가 실행 중인 위치(어떤 슬라이스)를 확인하세요.systemd-cgls

관련 정보