हार मानने की बजाए कैसे पीछे हटें


24

मैं दो चीजें करना चाहता हूं:

  1. इतनी तेजी से एक असफल प्रक्रिया का जवाब देने की कोशिश करना बंद करो
  2. प्रतिक्रिया देने की कोशिश कभी मत छोड़ो

एक आदर्श दुनिया में, अपस्टार्ट 1s के बाद एक मृत प्रक्रिया को फिर से शुरू करने की कोशिश करेगा, फिर प्रत्येक प्रयास पर उस देरी को दोगुना कर देगा, जब तक कि यह एक घंटे तक न पहुंच जाए।

क्या ऐसा कुछ संभव है?


never give up trying to respawnअनुत्तरित रहता है। किसी को?
वीएमवी

जवाबों:


29

अपस्टार्ट कुकबुक एक पोस्ट-स्टॉप देरी ( http://upstart.ubuntu.com/cookbook/#delay-respawn-of-a-job ) की सिफारिश करता है । respawnदलीलों के बिना छंद का उपयोग करें और यह हमेशा के लिए जारी रहेगा:

respawn
post-stop exec sleep 5

(मुझे यह उबंटू प्रश्न पूछें )

घातीय विलंब भाग को जोड़ने के लिए, मैं पोस्ट-स्टॉप स्क्रिप्ट में एक पर्यावरण चर के साथ काम करने की कोशिश करूँगा, मुझे लगता है कि कुछ इस तरह है:

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

** EDIT **

केवल विलंब करते समय, जब वास्तविक स्टॉप पर देरी हो रही है, तो टालें, निम्न का उपयोग करें, जो जाँचता है कि वर्तमान लक्ष्य "स्टॉप" है या नहीं:

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
यदि आप प्रतिक्रिया के बिना रिस्पॉन्स का उपयोग करते हैं, तो इसे पांच मिनट की विंडो में दस गुना तक पुन: प्रयास करने के लिए डिफ़ॉल्ट है।
जेमी कॉकबर्न

3
एक उत्पादन प्रणाली के लिए इसके साथ समस्या यह है कि एक बार जब आप अधिकतम (60 के दशक) तक पहुंच जाते हैं, तो यह हमेशा 60 सेकंड का समय लेगा, भले ही यह प्रणाली वापस स्वस्थ हो। हो सकता है post-startकि इसे 1. पर रीसेट किया जा सकता है
जोस एफ। रोमनियलो

2
@JamieCockburn डिफ़ॉल्ट अंतराल 5 मिनट नहीं है, यह 5 सेकंड है
ज़िट्रैक्स

1
यह लगभग मेरे लिए काम करता है - लेकिन सेट-इनवेट ट्रिक हिट "इनिटक्टल: पीआईडी ​​1 नौकरी के माहौल को संशोधित करने की अनुमति नहीं है"। इसके बजाय मुझे नींद के मूल्य को / tmp / $ UPSTART_JOB में संग्रहीत करने और फिर इसे वापस लाने के लिए सहारा लेना पड़ा
Neil McGill

5

जैसा कि पहले ही उल्लेख किया गया है, respawnरिस्पांस को ट्रिगर करने के लिए उपयोग करें।

हालाँकि, अपस्टार्ट कुकबुक कवरेजrespawn-limit कहती है कि आपको respawn limit unlimitedनिरंतर रिट्रीट व्यवहार को निर्दिष्ट करने की आवश्यकता होगी ।

डिफ़ॉल्ट रूप से यह तब तक पुनः प्रयास करेगा जब तक कि प्रक्रिया 5 सेकंड में 10 से अधिक बार प्रतिक्रिया नहीं करती है।

इसलिए मैं सुझाव दूंगा:

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

4

मैंने startएक क्रोनजॉब में डाल दिया । यदि सेवा चल रही है, तो इसका कोई प्रभाव नहीं है। यदि यह नहीं चल रहा है, तो यह सेवा शुरू करता है।


3
इतनी जानदार और इतनी खूबसूरत! <३
पोच

3

मैंने रोजर के उत्तर में सुधार किया है। आमतौर पर आप बैकऑफ़ करना चाहते हैं जब अंतर्निहित सॉफ़्टवेयर में कोई समस्या होती है जिसके कारण यह बहुत कम समय में क्रैश हो जाता है, लेकिन एक बार सिस्टम के पुनर्प्राप्त होने के बाद आप बैकऑफ़ समय को रीसेट करना चाहते हैं। रोजर के संस्करण में सेवा हमेशा 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आप क्या हासिल करने की कोशिश अनुमान लगाने के लिए। संदर्भ के लिए आदमी 5 init अनुभाग देखें respawn limit


6
वह अवधि वह अवधि है जिसमें रिस्पना की गिनती की जाती है , न कि रिस्पना के बीच देरी।
फ़ेडबाई

1
जो मुझे लगता है कि अगर आप respawn limit 10 360010 कोशिशों का उपयोग करते हैं , तो इसका मतलब है कि संभवतः तुरंत उपयोग किया जाएगा - क्योंकि डिफ़ॉल्ट रूप से कोई देरी नहीं है।
१२:३३ पर Zitrax

0

दूसरों ने रिस्पॉन्स और रेस्पॉन्स लिमिट स्टैंज़ के लिए सवाल का जवाब दिया है, लेकिन मैं पोस्ट-स्टॉप स्क्रिप्ट के लिए अपना समाधान जोड़ना चाहूंगा जो पुनरारंभ करने के बीच देरी को नियंत्रित करता है।

रोजर ड्यूक द्वारा प्रस्तावित समाधान के साथ सबसे बड़ी समस्या यह है कि देरी 'पुनः आरंभ नौकरीनाम' का कारण बनती है जब तक कि नींद पूरी न हो जाए।

मेरा जोड़ यह देखने के लिए जांचता है कि सोने के लिए या नहीं निर्धारित करने से पहले प्रगति में पुनरारंभ है या नहीं।

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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.