Bagaimana cara memulai kembali proses latar belakang linux secara otomatis jika gagal?

32

Saya memiliki proses yang dijalankan oleh skrip init.d di latar belakang. Misalnya:

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

Dalam kondisi tertentu, myprocess dapat gagal dan kembali. Apakah ada cara (standar) bagaimana mendeteksi kegagalannya dan memulai kembali secara otomatis?

Honza
sumber
Tentu, tetapi bervariasi berdasarkan distribusi. Hampir semua dari mereka menyediakan semacam manajer layanan.
David Schwartz
Tidak ada distribusi standar, tetapi buildroot. Jadi saya harus melakukannya secara manual ...
Honza

Jawaban:

14

Cara termudah adalah menambahkannya ke / etc / inittab , yang dirancang untuk melakukan hal semacam ini:

respawn Jika prosesnya tidak ada, mulailah prosesnya. Jangan menunggu penghentiannya (lanjutkan memindai file / etc / inittab). Mulai ulang proses ketika mati. Jika ada proses, jangan lakukan apa-apa dan lanjutkan memindai file / etc / inittab.

Misalnya, Anda bisa melakukan ini:

# Run my stuff
myprocess:2345:respawn:/bin/myprocess
Alan Shutko
sumber
Catatan, /etc/inittabberfungsi (atau bahkan ada) jika dan hanya jika Anda memiliki sistem init berbasis sysvinit. Dengan pemula dan dengan systemd tidak. Anda harus menginstal busybox (shell yang sangat primitif membuat sysadm memulihkan tugas menjadi menyakitkan, tetapi ia dapat menggantikan initd yang kompatibel dengan sysvinit) atau sysvinit (ini adalah fosil). Dalam wadah buruh pelabuhan, hanya yang pertama tidak menyakitkan.
peterh mengatakan mengembalikan Monica
27

Buildroot memiliki tiga sistem init yang memungkinkan, jadi ada tiga cara untuk melakukan ini:

BusyBox init

Dengan ini, seseorang menambahkan entri ke /etc/inittab.

::respawn:/bin/myprocess

Perhatikan bahwa BusyBox initmemiliki /etc/inittabformat istimewa . Bidang kedua tidak ada artinya, dan bidang pertama bukan ID tetapi nama perangkat.

Linux "Sistem V" init

Sekali lagi, seseorang menambahkan entri ke /etc/inittab.

myprocess:2345:respawn:/bin/myprocess

systemd

Seseorang menulis file unit di, katakanlah /etc/systemd/system/myprocess.service,:

[Unit]
Description=My Process

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

[Install]
WantedBy=multi-user.target

Aktifkan ini untuk mulai otomatis saat boot dengan:

systemctl enable myprocess.service

Mulai secara manual dengan:

systemctl start myprocess.service

Bacaan lebih lanjut

JdeBP
sumber
tetapi ketika Anda menggunakan pendekatan ini inittab maka proses Anda tidak lagi dapat diakses melalui antarmuka 'layanan' kan? yaitu Anda tidak bisa pergi service mything startatau service mything stoplagi .... apakah ada cara untuk mendapatkan yang terbaik dari keduanya? yaitu layanan sysvinit yang tidak dapat dipercaya, tetapi juga dapatkah digunakan melalui 'layanan'?
horseyguy
25

Bagaimana dengan membuat subkulit dengan loop yang terus memanggil proses yang sama?

Jika itu berakhir, iterasi loop berikutnya berjalan dan mulai lagi.

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

Jika subshell mati, itu sudah berakhir. Satu-satunya kemungkinan dalam kasus itu adalah membuat proses lain (saya akan menyebutnya necromancer) yang memeriksa apakah proses Anda masih hidup, mulai jika tidak dan jalankan necromancer ini dengan cron, sehingga Anda dapat memeriksanya secara teratur.

Langkah selanjutnya akan bertanya-tanya apa yang bisa terjadi jika cron meninggal, tetapi pada titik tertentu Anda harus merasa aman dan berhenti khawatir.

Trylks
sumber
3

Anda bisa memanfaatkan Monit . Ini sangat mudah digunakan dan cukup fleksibel. Lihat misalnya konfigurasi ini untuk memulai kembali proses Tomcat pada kegagalan.

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

Ini juga memiliki banyak contoh konfigurasi untuk banyak kasus penggunaan.

Clyde D'Cruz
sumber
1

Jika Anda bukan pengguna super atau root, dan jika sistem Linux Anda menginstal Docker, maka Anda dapat membuat gambar buruh pelabuhan dari proses Anda, menggunakan buruh pelabuhan untuk memulai kembali proses Anda jika sistem di-boot ulang.

File: 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

Untuk memulai wadah buruh pelabuhan Anda,

docker-compose up -d

Saya merasa mudah untuk menangani proses saya sendiri dengan restart otomatis jika saya bukan pengguna super sistem.

Untuk contoh contoh cara membuat gambar buruh pelabuhan, berikut adalah contoh cepat:

File: 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"]
Michael Qin
sumber
0

Dalam kasus saya, sebagai perbaikan cepat, saya memodifikasi dan menggunakan solusi @Trylks untuk membungkus program yang saya luncurkan. Saya ingin itu berakhir hanya pada jalan keluar yang bersih.

Harus dijalankan di sebagian besar shell:

#!/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) &
pengguna9869932
sumber
0

Anda dapat menggunakan restarter

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

Pada sistem yang lebih baru gunakan systemd yang memecahkan semua masalah sepele itu

sivann
sumber