在我的Django網絡應用程序中,我有一個工作程序,它是速率受限的API的客戶端,負責處理來自服務器線程的對該API的所有請求。我使用我的數據庫來存儲任務隊列。任務可以大批量進行,或根本不會。我正在使用事件循環來輪詢隊列並管理任務之間的延遲,以防萬一超過速率限制(限制是動態的)。這一切都可以正常工作,但是我唯一想做的其他事情是讓工作人員在隊列變干時停止點擊數據庫,並且讓我的Django應用程序向工作人員發出隊列不再存在的信號再次乾燥。Django應用程序的工作進程的異步事件
示意性地,在僞Python的它看起來像這樣:
state = NORMAL
delay_time = NORMAL_DELAY
while True:
sleep(delay_time)
if state == DORMANT:
continue
task = get_next_task() # hits database
if task is None:
state = DORMANT
delay_time = NORMAL_TIME
try:
execute(task)
except RateExceeded:
delay_time = backoff(delay_time)
else:
delay_time = NORMAL_DELAY
# Triggered by web layer
def asynchronous_event():
state = NORMAL
我要麼需要一個異步事件從可設置狀態恢復到正常(這將在sleep
執行)網絡層或一些觸發其他輕量級檢查,不會增加不必要的循環DB查詢。
在單機設置中,我只能使用信號,但顯然這在多機設置中不起作用。我試圖不必爲了這個信號的目的而運行單獨的消息隊列服務器。我使用Dotcloud進行託管,以便可以使用基於網絡的解決方案。理想情況下,與信號處理程序一樣易於實現。我研究過ZeroRPC,但是我不確定如何將它合併到我的事件循環中。
任何想法?
編輯
我期待到ZeroMQ來解決這個問題,但我可以使用一些幫助。棘手的部分是將有多個併發的webserver實例,並且在重新部署時,我需要從一個工作者到其後繼者的平穩過渡。因此,請耐心等待,因爲我的術語可能不正確,在我看來,最好的做法是讓每個工作人員異步地將其作爲郵箱進行綁定,並在主循環中將其從休眠模式中喚醒。每名工人在其IP的數據庫中創建一個記錄,並用創建日期加蓋時間戳。提交請求時,Web服務器向所有工作人員發佈消息。當工作人員收到一條消息時,它會檢查它是否具有最新創建日期的工作人員:如果是,則會處理該消息,如果沒有,則會自行終止。
這看起來很麻煩,但我想要正確,因爲我可能會在我的應用程序的其他地方使用這種模式。
如果您已經在使用Redis,則可以將其用作輕量級隊列。這會將它從數據庫中一起移除,而且速度非常快。 –
聽起來不錯,但我還沒有使用Redis。如果這是唯一不錯的選擇,我可能只需要把它弄糟。 – acjay
如果您正在查看ZeroMQ並且您正在使用Python,則應該查看ZeroRPC。它有助於抽象出很多ZeroMQ的複雜性。 –