2012-08-23 163 views
29

我運行一個工人的多個實例,如這個答案說明:Starting multiple upstart instances automatically重新啓動新貴實例處理

問:我可以重新啓動所有情況下一次?

要開始我的工作人員,我可以這樣做:

initctl的開始我的同事

,然後讓我做的事情:

initctl的狀態工人N = 1名工人(1)啓動/運行,進程551

initctl狀態worker N = 2 worker(2)start /運行,處理552

有沒有辦法做這樣的事情:

initctl的重新啓動我的同事

我希望能夠重新啓動所有實例,而不必知道有多少人在跑步。

這裏是我的我的,workers.conf

start on stopped cloud-init 
stop on shutdown 

env NUM_WORKERS=4 

script 
    for i in `seq 1 $NUM_WORKERS` 
    do 
     start worker N=$i 
    done 
end script 

而且worker.conf

stop on shutdown 

chdir /path/to/current 

respawn 

instance $N 

script 
    exec su -c "/home/worker/.rvm/bin/rvm-shell -c 'bundle exec rake work 2>&1 >> /var/log/worker-$N.log'" worker 
end script 

回答

35

worker.conf你只需要改變這一行:

stop on shutdown 

要:

stop on stopping my-workers 

並更改my-workers.conf使用pre-start而不是script

pre-start script 
    for i in `seq 1 $NUM_WORKERS` 
    do 
    start worker N=$i 
    done 
end script 

現在my-workers將保持狀態:由於工作pre-start發生,my-workers主要過程將不存在,所以不會退出。 stop on stopping my-workers導致工人停止,只要my-workers停止。當然,當它再次啓動時,它將再次啓動工人。

(FYI,stop on shutdown什麼都不做,因爲shutdown不是系統事件。man upstart-events所有定義的事件),所以你也應該改變我的同事到stop on runlevel [06]

+4

我花了一段時間來理解你的意思,但一旦我得到了它... *頭腦吹* – Evgeny

+0

@Evgeny同樣在這裏,哈哈。如果和我一樣,也許是Evgeny,你只花了5分鐘試圖理解這裏發生了什麼:基本上,my-workers.conf產生了多個暴發戶腳本和退出,但是每個worker.conf現在都有一條停止阻止我的工人',所以當你試圖阻止已經停止的員工流程時,工人們仍然會聽它並死。所以,「重新啓動」我的工作人員,即使它之前沒有真正運行,也會導致殺死工人(停止)並再次運行預啓動腳本(啓動),再次產生它們。 – Mahn

+1

它的作品,但它是相當hackish。事實上,「服務我的工作人員開始」會掛起。 Upstart文檔指出:「所有的作業文件都必須有一個可執行文件或腳本節。」預啓動腳本和後停腳本 - 這些預計不會啓動進程,事實上,它們不能啓動。也許最好是創造另一個停止或重新啓動員工的工作。 –

7

我的例子試圖從上方和SpamapS回答,我收到:

init: my-workers pre-start process (22955) terminated with status 127 

/var/log/upstart/my-workers.log我發現這個問題:

/proc/self/fd/9: 6: /proc/self/fd/9: end: not found 

的for循環my-workers.conf似乎是錯誤的語法end。 我換成

script 
    for i in `seq 1 $NUM_WORKERS` 
    do 
     start worker N=$i 
    done 
    end 
end script 

script 
    for i in `seq 1 $NUM_WORKERS` 
    do 
    start worker N=$i 
    done 
end script 

和它的工作!

+1

太棒了,爲我工作! –

1

考慮加入到worker.conf多了一個事件:

stop on shutdown or workers-stop 

然後你可以在命令行調用

sudo initctl emit workers-stop 

您可以添加類似的活動開始的工人。要實現重新啓動所有員工,創建一個任務,該任務將發出工人 - 停止,然後發出工人 - 啓動事件。

0

本質上,您需要一個爲您的N=1,N=2組合執行許多stopstart命令的過程。

一個簡單的方法是在exec script節內使用幾個bash for循環。但是,如果這些過程需要一些時間來停止(例如,因爲他們正在處理某些事情,並且在處理完他們當前的工作後他們正在接受SIGTERM),這是低效的,因爲在發送信號到下一個之前必須等待一個人停止。

因此,我建立了在https://github.com/elifesciences/builder-base-formula/blob/master/elife/config/etc-init-multiple-processes-parallel.conf

阻止他們並行的腳本由鹽作爲輸入編制地圖的過程的名字來究竟有多少暴發戶腳本。下面是一個簡單的結果:

description "(Re)starts all instances, in parallel" 
# http://upstart.ubuntu.com/cookbook/#start-on 
start on (local-filesystems and net-device-up IFACE!=lo) 
task 
script 
    timeout=300 
    echo "--------" 

    echo "Current status of 5 elife-bot-worker processes" 
    echo "Now is" $(date -Iseconds) 
    for i in `seq 1 5` 
    do 
     status elife-bot-worker ID=$i || true 
    done 
    echo "Stopping asynchronously 5 elife-bot-worker processes" 
    echo "Now is" $(date -Iseconds) 
    for i in `seq 1 5` 
    do 
     (stop elife-bot-worker ID=$i &) || true 
    done 

    for i in `seq 1 5` 
    do 
     echo "Waiting for elife-bot-worker $i to stop" 
     echo "Now is" $(date -Iseconds) 
     counter=0 
     while true 
     do 
      if [ "$counter" -gt "$timeout" ] 
      then 
       echo "It shouldn't take more than $timeout seconds to kill all the elife-bot-worker processes" 
       exit 1 
      fi 
      status elife-bot-worker ID=$i 2>&1 | grep "Unknown instance" && break 
      sleep 1 
      counter=$((counter + 1)) 
     done 
    done 
    echo "Stopped all elife-bot-worker processes" 

    echo "Starting 5 elife-bot-worker processes" 
    for i in `seq 1 5` 
    do 
     start elife-bot-worker ID=$i 
    done 
    echo "Started 5 elife-bot-worker processes" 

end script