Başarısız olursa linux arka plan işlemi otomatik olarak nasıl yeniden başlatılır?


32

Arka planda init.d betiği tarafından yürütülen bir işlem var. Örneğin:

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

Belirli koşullarda işlemim başarısız olabilir ve geri dönebilir. Başarısızlığını tespit etmenin ve otomatik olarak yeniden başlatmanın (standart) bir yolu var mı?


Tabii, fakat dağılıma göre değişir. Neredeyse hepsi bir tür servis yöneticisi sağlıyor.
David Schwartz

Standart bir dağıtım yoktur, fakat buildroot. Bu yüzden el ile yapmak zorundayım ...
Honza

Yanıtlar:


14

En kolay yol , bu tür bir şeyi yapmak için tasarlanmış / etc / inittab dosyasına eklemektir :

respawn Eğer işlem mevcut değilse, işlemi başlatın. Sonlandırılmasını beklemeyin (/ etc / inittab dosyasını taramaya devam edin). Öldüğünde işlemi yeniden başlatın. İşlem varsa, hiçbir şey yapmayın ve / etc / inittab dosyasını taramaya devam edin.

Örneğin, bunu yapabilirsin:

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

Unutmayın, /etc/inittabsadece sysvinit tabanlı bir init sisteminiz varsa ve çalışırsa (hatta mevcut). Başlangıç ​​ve sistemd ile değil. Ya yüklemek zorunda busybox (sysadm ağrılı görevleri kurtarmak yapma çok ilkel kabuk, ama bir sysvinit uyumlu initd yerine geçebilir) veya sysvinit (bir fosil olduğu). Liman işçisi konteynırında sadece ilki ağrılı değildir.
peterh, Monica

27

Buildroot'un üç olası init sistemi vardır, bu yüzden bunu yapmanın üç yolu vardır:

BusyBox init

Bununla, biri bir giriş ekler /etc/inittab.

::respawn:/bin/myprocess

BusyBox'ın initkendine özgü bir /etc/inittabformatı olduğunu unutmayın . İkinci alan anlamsız ve ilk alan bir kimlik değil, bir cihaz ad.

Linux "Sistem V" init

Yine, biri bir giriş ekler /etc/inittab.

myprocess:2345:respawn:/bin/myprocess

systemd

Biri bir birim dosyası yazar /etc/systemd/system/myprocess.service:

[Unit]
Description=My Process

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

[Install]
WantedBy=multi-user.target

Bunun açılışta otomatik olarak başlatılmasını sağlayın:

systemctl enable myprocess.service

Şununla manuel olarak başlayın:

systemctl start myprocess.service

daha fazla okuma


Ancak bu yaklaşımı inittab kullandığınızda, işleminize 'servis' arayüzü hakkı ile erişilemez. yani gidemezsin service mything startya da service mything stopartık .... ikisinden de en iyisini elde etmenin bir yolu var mı? yani, kilitlenemeyen sysvinit servisi, ancak 'hizmet' aracılığıyla da kullanılabilir mi?
horseyguy

25

Sürekli aynı işlemi çağıran bir döngü ile alt kabuk oluşturma hakkında ne?

Biterse, döngünün bir sonraki tekrarlaması devam eder ve tekrar başlatır.

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

Alt kabuk ölürse, bitti. Bu durumda tek olasılık, işleminizin canlı olup olmadığını kontrol eden başka bir işlem ("ben büyücü olarak adlandırırım"), işlemin canlı olup olmadığını kontrol etmek ve bu büyücüyü cron ile çalıştırmak, böylece düzenli olarak kontrol edebilmeniz olacaktır.

Bir sonraki adım, cron ölürse ne olabileceğini merak etmek olacaktır, ancak bir noktada kendinizi güvende hissetmeli ve endişelenmeyi bırakmalısınız.


3

Monit’i kullanabilirsin . Kullanımı gerçekten çok kolay ve oldukça esnek. Başarısızlık durumunda Tomcat işlemini yeniden başlatmak için bu yapılandırmaya bakınız.

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

Ayrıca birçok kullanım durumu için birçok yapılandırma örneği vardır .


1

Süper bir kullanıcı veya kök değilseniz ve Linux sisteminizde Docker yüklü ise, sistem yeniden başlatılırsa işleminizi yeniden başlatmak için docker kullanarak işleminizin bir docker görüntüsünü oluşturabilirsiniz.

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

Liman konteynerinizi başlatmak için,

docker-compose up -d

Sistemin süper kullanıcısı değilsem, kendi işlemimi otomatik yeniden başlatma ile işlemenin kolay olduğunu düşünüyorum.

Liman işçisi görüntüsünün nasıl oluşturulacağına dair örnek bir örnek için, hızlı bir örnek:

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

Benim durumumda, hızlı bir düzeltme olarak, başlattığım programı sarmak için @Trylks çözümünü değiştirdim ve kullandım. Sadece temiz çıkışta bitmesini istedim.

Çoğu mermide koşmalı:

#!/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

Yeniden başlatıcı kullanabilirsiniz

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

Yeni sistemlerde, tüm bu önemsiz sorunları çözen systemd kullanın

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.