2014-01-15 55 views
5

我最近開始在一個新的Django項目中使用芹菜。設置:WorkerLostError('工人過早退出:信號15(SIGTERM)。')

-------------- [email protected] v3.1.7 (Cipater) 
---- **** ----- 
--- * *** * -- Linux-3.8.11-ec2-x86_64-with-debian-squeeze-sid 
-- * - **** --- 
- ** ---------- [config] 
- ** ---------- .> app:   nextlanding_api:0x1c23250 
- ** ---------- .> transport: redis://[email protected] 
- ** ---------- .> results:  djcelery.backends.database:DatabaseBackend 
- *** --- * --- .> concurrency: 4 (prefork) 
-- ******* ---- 
--- ***** ----- [queues] 
-------------- .> celery   exchange=celery(direct) key=celery 

software -> celery:3.1.7 (Cipater) kombu:3.0.8 py:2.7.4 
      billiard:3.3.0.13 redis:2.9.0 
platform -> system:Linux arch:64bit, ELF imp:CPython 
loader -> celery.loaders.app.AppLoader 
settings -> transport:redis results:djcelery.backends.database:DatabaseBackend 

我們正在調查中,任務與ETA 24+小時是消失的問題(我已經確保了visibility_timeout爲> 24小時)。當我熱烈關閉工作人員時,日誌語句顯示正在確認的幾條消息。例如: Restoring 26 unacknowledged message(s).

但是,我預計約50個左右未確認的消息要恢復。看看我的日誌更接近,我看到:

[ERROR] celery.worker.job: Task myproj_task[xxx] raised unexpected: WorkerLostError('Worker exited prematurely: signal 15 (SIGTERM).',) 
... 
WorkerLostError: Worker exited prematurely: signal 15 (SIGTERM). 
Restoring 26 unacknowledged message(s). 
Process exited with status 0 

我見過其他人報告OOM殺死他們的過程。我在Heroku上,沒有看到R14的代碼。

上下文的最後一點,我從我的任務中產生新的進程。

我的問題是:WorkerLostError是我應該擔心的事情嗎?狀態碼是15(SIGTERM),似乎沒問題。如果這個錯誤不正常,是否會失去ETA任務?

編輯

起初,我以爲項目是消失但只是在一些詳細日誌後,可以看我的任務是發行,但在Redis的永遠堅持:

myproj_email_task was sent. task_id: b6ce2b97-d5b8-4850-9e43-9185426cd9f6

但是,查看redis中的任務,任務b6ce2b97-d5b8-4850-9e43-9185426cd9f6不存在。

所以它會顯示任務不會消失,但要麼根本沒有被髮送,要麼沒有被放入到redis密鑰中unacked

+0

與'正常'任務相同的問題,不是eta或倒計時。工人剛剛死亡,留下了大量的記憶。你有沒有發現是什麼引起了你的? – kev

+0

我離開了芹菜,但我認爲這個問題與使用數據庫作爲人造消息隊列有關。一旦我轉移到redis或rabbitmq,我認爲這個問題已經解決了。 –

+0

你現在只是使用普通redis/rabbitmq?但是你仍然在使用Python? – kev

回答

0

WorkerLostError是不正常的,你一定要擔心。對於長時間運行的工作,ack/restart:芹菜做得最好,但如果你偏執狂,並且即使父母/工作人員在特殊情況下死亡,你也期待有保證的交付/執行/確認模型,你可以考慮使用一個次要數據存儲跟蹤進度和元數據,使你有細粒度的控制:在SIGTERM

Client->TransactionalDB: insert JOB 
Client->Celery: send_async(job_id) 
Celery->Worker: do(job_id) 
Worker->TransactionalDB: update started job + meta 
... 
Worker->TransactionalDB: update progress + meta 
... 
?->Worker: die! 
... 
Celerybeat->Worker: checkForOrphans() 
Worker->TransactionalDB: select where ... 
0

WorkerLost肯定是不正常的。在這種情況下如何重新啓動流程而不會丟失任務?即使ack_late選項也沒有幫助。

我認爲不想失去SIGTERM任務的願望遠不是偏執狂。

4

這些WorkerLostErrors的原因很可能芹菜的Heroku的行爲之間的不兼容:

  • 芹菜工人預計父工作進程SIGTERM,在這種情況下,它可以讓其子進程結束他們當前的任務。
  • 當進行一個測試儀的「熱關機」時,Heroku發送一個SIGTERM給測功機中的所有進程。

因此,所有工作程序子進程也會獲得SIGTERM,並立即開始終止,導致WorkerLostErrors。

一種解決方法已經爲尚未發佈的芹菜4.0編寫:https://github.com/celery/celery/issues/2839

我還沒有找到一個解決方案,但3.1.19。

0

今天我有同樣的問題。我有一個派生子流程和執行隨機與

WorkerLostError中斷的任務(「工人過早地退出:信號15(SIGTERM)

最後我發現,它的原因是這裏: 我用multiprocessing.Pool產生新進程:

from multiprocessing import Pool as ThreadPool 
pool = ThreadPool(2) 
data = pool.map(some_func, some_data) 
pool.terminate() 

似乎pool.terminate()有時發送SIGTERM不僅催生過程,但其自身也 瓦en我已將pool.terminate()更改爲:

pool.join() 
pool.close() 

一切都變好了。