리눅스 백그라운드 프로세스가 실패하면 자동으로 다시 시작하는 방법은 무엇입니까?


32

백그라운드에서 init.d 스크립트로 실행되는 프로세스가 있습니다. 예 :

case "$1" in 
    start)
       /bin/myprocess &
    stop)
       killall myprocess
    restart)
       killall myprocess
       /bin/myprocess &
esac

특정 조건에서는 myprocess가 실패하고 돌아올 수 있습니다. 실패를 감지하고 자동으로 다시 시작하는 방법이 있습니까?


물론 배포판에 따라 다릅니다. 그들 대부분은 일종의 서비스 관리자를 제공합니다.
David Schwartz

표준 배포판은 없지만 buildroot가 있습니다. 그래서 수동으로해야합니다.
Honza

답변:


14

가장 쉬운 방법은 이것을 / etc / inittab 에 추가하는 것입니다. 이것은 이런 종류의 작업을 수행하도록 설계되었습니다.

respawn respawn 프로세스가 존재하지 않으면 프로세스를 시작하십시오. 종료 될 때까지 기다리지 마십시오 (/ etc / inittab 파일 스캔 계속). 프로세스가 종료되면 다시 시작하십시오. 프로세스가 존재하면 아무 것도하지 않고 / etc / inittab 파일 스캔을 계속하십시오.

예를 들어 다음과 같이 할 수 있습니다.

# Run my stuff
myprocess:2345:respawn:/bin/myprocess

참고 /etc/inittab작품 (또는 존재) 만약 당신이 Sysvinit의 기반 초기화 시스템이있는 경우에만. upstart와 systemd는 그렇지 않습니다. 당신이 중 하나를 설치해야 비지 박스 (SYSADM 그 고통스러운 작업을 복구하고 아주 원시적 인 쉘을하지만,이 Sysvinit의 호환 initd 대체 할 수 있습니다) 또는 Sysvinit의을 (그것은 화석이다). 도커 컨테이너에서는 첫 번째 컨테이너 만 아프지 않습니다.
peterh는 모니카

27

Buildroot에는 세 가지 가능한 초기화 시스템이 있으므로이를 수행하는 세 가지 방법이 있습니다.

BusyBox init

이를 통해에 항목을 추가합니다 /etc/inittab.

::respawn:/bin/myprocess

BusyBox init는 고유 한 /etc/inittab형식을 가지고 있습니다. 두 번째 필드는 의미가 없으며 첫 번째 필드 는 ID가 아니라 장치 기본 이름입니다.

리눅스 "시스템 V" init

다시 한번,에 항목을 추가합니다 /etc/inittab.

myprocess:2345:respawn:/bin/myprocess

systemd

다음과 같이 유닛 파일을 씁니다 /etc/systemd/system/myprocess.service.

[Unit]
Description=My Process

[Service]
ExecStart=/bin/myprocess
Restart=always

[Install]
WantedBy=multi-user.target

부팅시 다음을 사용하여 자동 시작하려면 활성화하십시오.

systemctl enable myprocess.service

다음을 사용하여 수동으로 시작하십시오.

systemctl start myprocess.service

추가 자료


그러나이 접근법을 inittab을 사용하면 '서비스'인터페이스를 통해 프로세스에 더 이상 액세스 할 수 없습니까? 당신이 갈 수 없다하여 예 service mything start또는 service mything stop더 이상 .... 모두 최선을하는 방법은 무엇입니까? 즉, 깨지지 않는 sysvinit 서비스뿐만 아니라 'service'를 통해 사용할 수 있습니까?
horseyguy

25

지속적으로 동일한 프로세스를 호출하는 루프로 서브 쉘을 작성하는 것은 어떻습니까?

종료되면 다음 반복 루프가 진행되어 다시 시작됩니다.

(while true; do 
    /bin/myprocess
done) &

서브 쉘이 죽으면 끝납니다. 이 경우 유일한 가능성은 프로세스가 살아 있는지 확인하는 프로세스 (네크로맨서라고 부름)를 작성하고 프로세스가 존재하지 않으면 시작하고 크론으로이 네크로맨서를 실행하여 정기적으로 확인할 수 있도록하는 것입니다.

다음 단계는 cron이 죽으면 어떤 일이 일어날 지 궁금해 할 것입니다.


3

Monit 을 사용할 수 있습니다 . 정말 사용하기 쉽고 매우 유연합니다. 실패시 Tomcat 프로세스를 다시 시작하려면 예를 들어이 구성을 참조하십시오.

check process tomcat with pidfile /var/run/tomcat.pid
   start program = "/etc/init.d/tomcat start"
   stop  program = "/etc/init.d/tomcat stop"
   if failed port 8080 type tcp then restart

또한 많은 사용 사례에 대한 많은 구성 예제 가 있습니다.


1

수퍼 유저 또는 루트 사용자가 아니며 Linux 시스템에 Docker가 설치되어있는 경우 시스템이 재부팅되면 docker를 사용하여 프로세스를 다시 시작하여 프로세스의 docker 이미지를 작성할 수 있습니다.

파일 : docker-compose.yml

version: "3"
services:
  lserver:
    image: your_docker_image:latest
    ports:
    - 8080:8080   # just use 8080 as an example
    restart: always  # this is where your process can be guaranteed to restart

도커 컨테이너를 시작하려면

docker-compose up -d

시스템의 수퍼 유저가 아닌 경우 자동 재시작으로 내 프로세스를 쉽게 처리 할 수 ​​있습니다.

도커 이미지를 만드는 방법에 대한 샘플 예는 다음과 같습니다.

파일 : Dockerfile

FROM alpine:3.5

RUN apk update && apk upgrade && rm -rf /var/cache/apk/*
WORKDIR /app
COPY my-process-server /app
RUN ln -s /app/my-process-server /usr/local/bin/my-process-server

EXPOSE 8080

CMD ["my-process-server"]

0

필자의 경우 빠른 수정으로 @Trylks 솔루션을 수정하고 사용하여 시작한 프로그램을 래핑했습니다. 나는 깨끗한 출구에서만 끝내기를 원했습니다.

대부분의 쉘에서 실행해야합니다.

#!/bin/sh

echo ""
echo "Use: $0 ./program"
echo ""

#eg="/usr/bin/apt update"

echo "Executing $1 ..."

EXIT_CODE=1
(while [ $EXIT_CODE -gt 0 ]; do
    $1
    # loops on error code: greater-than 0
    EXIT_CODE=$?
done) &

0

재시동기를 사용할 수 있습니다

start)
   restarter -c /bin/myprocess &
stop)
   pkill -f myprocess

최신 시스템에서는 모든 사소한 문제를 해결하는 systemd를 사용하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.