2012-01-15 35 views
12

有人可以指導我如何在異常發生時拋出錯誤或錯誤發生時,齒輪工如何重試?錯誤條件和齒輪工重試?

我在Django應用程序中使用python gearman客戶端,我的工作人員是 作爲Django命令啓動。我從這個blog post讀取,重試 從錯誤條件不是直截了當,它需要 sys.exit從工作端。

這個問題已被修復,可能使用sendFail或sendException重試? 還有齒輪人員支持重試指數算法 - 說如果 一個SMTP失敗發生在2,4,8,16秒後等待重試?

+0

sys.exit()對於Gearman來說是個不錯的主意 - 通常它會永遠重試任何這樣的作業(除非在守護進程啓動時設置了作業重試)。只要做一個帶有任何狀態/結果的'return stringvar'就可以了(例如鍵入數據庫行或緩存中的真實信息)。 – RichVel 2013-01-17 13:17:51

回答

25

就我的理解,Gearman採用了「這不是我的業務」的方法 - 例如,除非工作人員崩潰,否則它不會干涉所執行的工作。任何成功/失敗消息應該由客戶端處理,而不是Gearman服務器本身。

在前臺工作中,這意味着所有的sendFail()/sendException()和其他send*()都指向客戶端,由客戶決定是否重試該工作。這很有意義,因爲有時您可能不需要重試。

在後臺作業中,所有send*()函數都失去意義,因爲沒有客戶端會聽取回調。結果,發送的消息將被Gearman忽略。作業重試的唯一條件是工作人員崩潰時(可以通過exit(XX)命令模擬,其中XX是非零值)。當然,這不是你想要做的事情,因爲工作人員通常應該是長期運行的流程,而不是每次不成功的工作之後必須重新啓動的流程。

就我個人而言,我已經通過擴展默認的GearmanJob類來解決這個問題,在這裏我攔截了對send*()函數的調用,然後自己實現了重試機制。本質上,我將所有與重試相關的數據(最大重試次數,重試次數)與工作負載一起傳遞,然後自行處理所有事務。這有點麻煩,但我明白爲什麼Gearman以這種方式工作 - 它只是允許您處理所有的應用程序邏輯。

最後,關於以指數超時(或任何超時)重試作業的功能。 Gearman具有添加延遲作業的功能(在protocol documentation中查找SUBMIT_JOB_EPOCH),但我不確定其狀態--PHP擴展,我認爲Python模塊不支持它,文檔稱它可以在未來。但我明白它現在可行 - 你只需要向Gearman提交原始套接字請求就可以實現(並且指數部分也應該在你身邊實現)。

但是,this blog post認爲SUBMIT_JOB_EPOCH實現不能很好地擴展。他使用node.js和setTimeout()使其工作,我見過其他人使用unix實用程序at也這樣做。無論如何 - Gearman不會爲你做。它將專注於可靠性,但會讓你專注於所有的邏輯。

+5

我知道這是一個老問題的答案,但我看到很多人都在努力同樣的問題,我相信這是值得一提的全面圖片。 – Aurimas 2012-04-27 09:50:59