ทำอย่างไรให้พุ่งพรวดออกไปแทนที่จะยอมแพ้


24

ฉันต้องการพุ่งพรวดเพื่อทำสองสิ่ง:

  1. หยุดพยายามที่จะเกิดกระบวนการที่ล้มเหลวอย่างรวดเร็ว
  2. อย่ายอมแพ้พยายามที่จะเกิดใหม่

ในโลกอุดมคติอุดมคติพุ่งพรวดจะพยายามเริ่มกระบวนการที่ตายแล้วหลังจากผ่านไป 1 วินาทีจากนั้นเพิ่มความล่าช้านั้นเป็นสองเท่าของความพยายามแต่ละครั้งจนกว่าจะถึงหนึ่งชั่วโมง

เป็นไปได้อย่างนี้ไหม?


never give up trying to respawnยังไม่ได้ตอบ ใคร?
vemv

คำตอบ:


29

ตำราพุ่งพรวดแนะนำให้ชะลอการโพสต์ ( http://upstart.ubuntu.com/cookbook/#delay-respawn-of-a-job ) ใช้respawnบทที่ไม่มีข้อโต้แย้งและมันจะพยายามอย่างต่อเนื่องตลอดไป:

respawn
post-stop exec sleep 5

(ฉันได้รับสิ่งนี้จากคำถามถาม Ubuntu )

หากต้องการเพิ่มส่วนการหน่วงเวลาเอ็กซ์โปเนนเชียลฉันลองทำงานกับตัวแปรสภาพแวดล้อมในสคริปต์หลังหยุดฉันคิดว่า:

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

** แก้ไข **

เมื่อต้องการใช้การหน่วงเวลาเฉพาะเมื่อ respawning หลีกเลี่ยงความล่าช้าในการหยุดจริงใช้ต่อไปนี้ซึ่งตรวจสอบว่าเป้าหมายปัจจุบันเป็น "หยุด" หรือไม่:

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
หากคุณใช้ respawn โดยไม่มีอาร์กิวเมนต์ค่าเริ่มต้นจะลองใหม่ถึงสิบครั้งในหน้าต่างห้านาที
Jamie Cockburn

3
ปัญหาที่เกิดขึ้นกับสิ่งนี้สำหรับระบบที่ใช้งานจริงคือเมื่อคุณไปถึงจำนวนสูงสุด (60s) มันจะใช้เวลา 60 วินาทีเสมอแม้ว่าระบบจะกลับมามีสุขภาพดี อาจจะมี post-startการรีเซ็ตเป็น 1
José F. Romaniello

2
@JamieCockburn ช่วงเวลาเริ่มต้นไม่ได้ 5 นาทีก็ถึง 5 วินาที
Zitrax

1
สิ่งนี้เกือบจะได้ผลสำหรับฉัน - แต่เคล็ดลับ set-env เข้าชม "initctl: ไม่อนุญาตให้แก้ไขสภาพแวดล้อมงาน PID 1" แต่ฉันต้องหันไปใช้เพื่อเก็บค่าการนอนหลับใน / tmp / $ UPSTART_JOB แล้วจึงหามันกลับมาใหม่
Neil McGill

5

ดังที่ได้กล่าวไปแล้วใช้respawnเพื่อกระตุ้นการเกิดใหม่

อย่างไรก็ตามการครอบคลุมตำราอาหารพุ่งพรวดเมื่อวันที่respawn-limitกล่าวว่าคุณจะต้องระบุrespawn limit unlimitedให้มีพฤติกรรมลองใหม่อย่างต่อเนื่อง

โดยค่าเริ่มต้นมันจะลองอีกครั้งตราบใดที่กระบวนการไม่ตอบสนองมากกว่า 10 ครั้งใน 5 วินาที

ดังนั้นฉันขอแนะนำ:

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

4

ฉันลงเอยด้วยการstartcronjob หากบริการกำลังทำงานอยู่จะไม่มีผลใด ๆ ถ้ามันไม่ทำงานมันก็เริ่มให้บริการ


3
ช่างดูดีและสง่างามมาก! <3
pkoch

3

ฉันได้ปรับปรุงคำตอบของโรเจอร์แล้ว โดยทั่วไปคุณต้องการ backoff เมื่อมีปัญหาในซอฟต์แวร์พื้นฐานทำให้เกิดความผิดพลาดมากในช่วงเวลาสั้น ๆ แต่เมื่อระบบกู้คืนแล้วคุณต้องการรีเซ็ตเวลา backoff ในเวอร์ชันของ Roger บริการจะนอนเป็นเวลา 60 วินาทีเสมอแม้กระทั่งเกิดข้อขัดข้องเดี่ยวและแยกออกหลังจากเกิดปัญหา 7 ครั้ง

#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

คุณต้องการrespawn limit <times> <period>- แม้ว่าสิ่งนี้จะไม่ให้พฤติกรรมแบบเอ็กซ์โพเนนเชียลที่คุณกำลังมองหา แต่มันอาจจะใช้กับกรณีการใช้งานส่วนใหญ่ คุณอาจลองใช้ค่าที่มีขนาดใหญ่มากtimesและperiodเพื่อประมาณสิ่งที่คุณพยายามจะทำ ดูส่วนman 5 initบนrespawn limitสำหรับการอ้างอิง


6
ช่วงเวลาคือช่วงเวลาที่นับจำนวนการเกิดใหม่ไม่ใช่ความล่าช้าระหว่างการเกิดใหม่
fadedbee

1
ซึ่งฉันคิดว่าจะหมายความว่าแม้ว่าคุณจะใช้respawn limit 10 360010 ครั้งน่าจะถูกใช้งานได้ทันที - เนื่องจากค่าเริ่มต้นจะไม่มีการหน่วงเวลา
Zitrax

0

คนอื่น ๆ ได้ตอบคำถามสำหรับ respawn และ respawn limit stanzas แต่ฉันต้องการเพิ่มโซลูชันของตัวเองสำหรับสคริปต์ post-stop ที่ควบคุมการหน่วงเวลาระหว่างการรีสตาร์ท

ปัญหาที่ใหญ่ที่สุดของวิธีแก้ปัญหาที่เสนอโดย Roger Dueck คือความล่าช้าทำให้ 'restart jobName' หยุดทำงานจนกว่าการสลีปจะเสร็จสมบูรณ์

การเพิ่มของฉันจะตรวจสอบเพื่อดูว่ามีการรีสตาร์ทอยู่ระหว่างดำเนินการก่อนที่จะพิจารณาว่าจะเข้าสู่โหมดสลีปหรือไม่

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.