Kalkıştan vazgeçmek yerine geri dönüş nasıl yapılır


24

Upstart'ın iki şeyi yapmasını istiyorum:

  1. başarısız bir işlemi çok hızlı bir şekilde yeniden başlatmayı denemeyi bırak
  2. Asla pes etme

İdeal bir dünyada, start up 1s sonra ölü bir işlemi yeniden başlatmaya çalışacak, sonra her denemede bu gecikmeyi ikiye katlayacak, bir saate ulaşana kadar.

Böyle bir şey mümkün mü?


never give up trying to respawncevapsız kalır. kimse?
vemv

Yanıtlar:


29

Upstart Cookbook, durma sonrası bir gecikme süresi önerir ( http://upstart.ubuntu.com/cookbook/#delay-respawn-of-a-job ). respawnStanza'yı argüman olmadan kullanın ve sonsuza dek denemeye devam edecek:

respawn
post-stop exec sleep 5

(Bunu Ubuntu Ask sorusundan aldım )

Üstel gecikme bölümünü eklemek için, post-stop betiğinde bir ortam değişkeni ile çalışmayı deneyeceğim, sanırım şöyle bir şey:

env SLEEP_TIME=1
post-stop script
    sleep $SLEEP_TIME
    NEW_SLEEP_TIME=`expr 2 \* $SLEEP_TIME`
    if [ $NEW_SLEEP_TIME -ge 60 ]; then
        NEW_SLEEP_TIME=60
    fi
    initctl set-env SLEEP_TIME=$NEW_SLEEP_TIME
end script

** DÜZENLE **

Gecikmeyi yalnızca yeniden doğarken uygulamak için, gerçek bir duraktaki gecikmeden kaçınmak için, geçerli hedefin "durma" olup olmadığını denetleyen aşağıdakileri kullanın:

env SLEEP_TIME=1
post-stop script
    goal=`initctl status $UPSTART_JOB | awk '{print $2}' | cut -d '/' -f 1`
    if [ $goal != "stop" ]; then
        sleep $SLEEP_TIME
        NEW_SLEEP_TIME=`expr 2 \* $SLEEP_TIME`
        if [ $NEW_SLEEP_TIME -ge 60 ]; then
            NEW_SLEEP_TIME=60
        fi
        initctl set-env SLEEP_TIME=$NEW_SLEEP_TIME
    fi
end script

1
Bağımsız değişken olmadan respawn kullanıyorsanız, varsayılan olarak beş dakikalık bir pencerede on kereye kadar yeniden denemek için kullanılır.
Jamie Cockburn,

3
Bir üretim sistemi için buradaki problem, maksimuma (60'lara) ulaştığınızda, sistem sağlıklı hale gelse bile her zaman 60 saniye sürmesidir. Belki post-start1’e sıfırlama olabilir .
José F. Romaniello 17:16

2
@JamieCockburn Varsayılan aralık 5 dakika değil, 5 saniyedir .
Zitrax,

1
Bu neredeyse benim için işe yaradı - ancak set-env hilesi "initctl: PID 1 iş ortamını değiştiremez". Bunun yerine / tmp / $ UPSTART_JOB içindeki uyku değerini saklamak ve daha sonra geri almak için başvurmam gerekti
Neil McGill

5

Daha önce de belirtildiği gibi, respawnyeniden doğuşu tetiklemek için kullanın .

Ancak Upstart Cookbook kapsama alanı,respawn-limitrespawn limit unlimited sürekli yeniden deneme davranışı için belirtmeniz gerekeceğini söylüyor .

Varsayılan olarak, işlem 5 saniyede 10 defadan fazla tekrarlanmadığı sürece yeniden denenecek.

Bu nedenle şunu önerebilirim:

respawn
respawn limit unlimited
post-stop <script to back-off or constant delay>

4

startBir cronjob koyarak sona erdi . Servis çalışıyorsa, hiçbir etkisi olmaz. Çalışmıyorsa, servisi başlatır.


3
Çok neşeli ve zarif! <3
pkoch

3

Roger'ın cevabını iyileştirdim. Genelde, temeldeki yazılımda kısa sürede çokça çökmesine neden olan bir sorun olduğunda geri çekilmek istersiniz, ancak sistem düzeldiğinde geri dönüş süresini sıfırlamak istersiniz. Roger'ın versiyonunda servis, 7 çarpışmadan sonra tek ve yalıtılmış çarpmalar için bile her zaman 60 saniye boyunca uyuyacak.

#The initial delay.
env INITIAL_SLEEP_TIME=1

#The current delay.
env CURRENT_SLEEP_TIME=1

#The maximum delay
env MAX_SLEEP_TIME=60

#The unix timestamp of the last crash.
env LAST_CRASH=0

#The number of seconds without any crash 
#to consider the service healthy and reset the backoff.
env HEALTHY_TRESHOLD=180

post-stop script
  exec >> /var/log/auth0.log 2>&1
  echo "`date`: stopped $UPSTART_JOB"
  goal=`initctl status $UPSTART_JOB | awk '{print $2}' | cut -d '/' -f 1`
  if [ $goal != "stop" ]; then
    CRASH_TIMESTAMP=$(date +%s)

    if [ $LAST_CRASH -ne 0 ]; then
      SECS_SINCE_LAST_CRASH=`expr $CRASH_TIMESTAMP - $LAST_CRASH`
      if [ $SECS_SINCE_LAST_CRASH -ge $HEALTHY_TRESHOLD ]; then
        echo "resetting backoff"
        CURRENT_SLEEP_TIME=$INITIAL_SLEEP_TIME
      fi
    fi

    echo "backoff for $CURRENT_SLEEP_TIME"
    sleep $CURRENT_SLEEP_TIME

    NEW_SLEEP_TIME=`expr 2 \* $CURRENT_SLEEP_TIME`
    if [ $NEW_SLEEP_TIME -ge $MAX_SLEEP_TIME ]; then
      NEW_SLEEP_TIME=$MAX_SLEEP_TIME
    fi

    initctl set-env CURRENT_SLEEP_TIME=$NEW_SLEEP_TIME
    initctl set-env LAST_CRASH=$CRASH_TIMESTAMP
  fi
end script

1

İstediğiniz respawn limit <times> <period>- Bu, aradığınız üstel davranışı sağlamayacak olmasına rağmen, muhtemelen çoğu kullanım durumunda işe yarar. Sen çok büyük değerler kullanılarak deneyebilirsiniz timesve periodsize ulaşmak için deneyin neyi yaklaştığı. Referans için man 5 init bölümündeki bölüme bakınız respawn limit.


6
Dönem, yeniden doğanlar arasında bir gecikme değil, yeniden doğmaların sayıldığı süredir.
fadedbee

1
Tahmin edeyim ki respawn limit 10 3600, 10 denemeyi kullansanız bile hemen kullanılacağınız anlamına gelir - çünkü varsayılan olarak gecikme olmaz.
Zitrax,

0

Diğerleri yeniden doğmuş ve yeniden doğmuş limit stanzaları sorusunu cevapladılar, ancak yeniden başlatma arasındaki gecikmeyi kontrol eden post-stop komut dosyası için kendi çözümümü eklemek istiyorum.

Roger Dueck'in önerdiği çözümle ilgili en büyük sorun, gecikmenin 'yeniden başlatma işiAdı' nın uyku tamamlanana kadar askıda kalmasına neden olmasıdır.

Eklemem uykuda olup olmadığını belirlemeden önce devam eden bir yeniden başlatma olup olmadığını kontrol eder.

respawn
respawn limit unlimited

post-stop script
    goal=`initctl status $UPSTART_JOB | awk '{print $2}' | cut -d '/' -f 1`
    if [[ $goal != "stop" ]]; then
            if ! ps aux | grep [r]estart | grep $UPSTART_JOB; then
                    sleep 60
            fi
    fi
end script
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.