2015-07-06 77 views
2

我在Google App Engine(Python)上運行一個實驗性應用程序,它由一個API和一個執行一些長時間運行任務的Worker組成。管理Google App Engine中的長時間運行任務

API是一個具有云端點的標準模塊,Worker是ManagedVM模塊。

用戶在數據庫上創建一個任務,它將其作爲任務放在拉隊列中。工人通過延長租約來完成這項任務並無限地執行它。工作人員還將設置數據庫任務的狀態(例如「正在運行」或「錯誤」)。

sequence diagram of gae interaction

的目標是在用戶再次停止它永遠執行任務。我通過將狀態設置爲「停止」並在Worker上調用處理程序來停止任務(workerUrl保存到任務模型)來實現此目的。工作人員然後將狀態設置爲「停止」並刪除其租用的任務。

這個工作到目前爲止有一些小問題(例如,把任務兩次)。但我想知道是否有更好的方法來應對這一挑戰?基本上問題是如何使遠程工作人員執行與數據庫模型同步。

另外我也有問題,如果我停止應用程序的任務應根據他們的狀態放回隊列(可以有意停止)。在現場服務器上,這不是什麼大問題,因爲應用程序基本上不會停止,但在開發服務器上是這樣。也許這適用於cron工作?

更新1:

有關任務的信息實際上是存儲在數據庫中。隊列上的任務包含數據庫上模型的ID,請注意,圖中狀態在api上得到更新。

工作者(MVM)和API之間的通信通過我在工作端使用python客戶端的雲端點發生。這工作相當可靠。

這是真的,爲避免重複的任務,我應該使用任務名稱。我遇到的唯一問題是,你不能重複使用相同的名稱一段時間,所以我需要找出一些任務名稱,可能包括時間戳。

我選擇任務隊列而不是某些數據庫唯一方法的原因是隨附的故障轉移機制。由於我的工人很可能會失敗,所以另一名工人將完成任務。另外它減少了數據庫調用和api調用。

我想我會去重構在它自己的模型中的「任務狀態」來建立一種命令模型。這也將作爲任務的日誌,因此可以看到執行級別發生了什麼。也許這與任務隊列一起工作,如果沒有,我會看看我是否可以刪除隊列。

回答

1

這聽起來像你只是希望Worker和AP​​I前端共享存儲,而你的解決方案是使用任務隊列作爲該存儲。更好的做法是使用Worker的Cloud Datastore的REST API。您仍然可以使用拉隊列來啓動工作(並避免將同一任務租給多個工作人員),但是可以使用相應的數據存儲記錄在API前端和Worker之間傳遞更新。例如,API前端存儲「停止」請求,然後Worker在它運行時進行輪詢。

請注意,App Engine上的API前端可以同時提交到同一個事務中的數據存儲和任務隊列。這樣可以更加可靠地設置共享記錄和任務。

至於避免重複的任務,請考慮任務名稱。您可以爲任務分配名稱以防止使用相同名稱創建兩個任務。

我不確定如何在開發過程中最好地設置GAE API前端和託管VM worker後端,如果他們共享數據存儲。也許他們都需要使用數據存儲REST API和開發特定項目,並且API前端需要「如果開發服務器使用REST,否則使用本地數據存儲API」封裝。 (如果有更好的方法,我會很高興的知道它,但對於託管虛擬機我還是個新手。)對於你的問題,我將補充說,dev服務器會在運行之間保留自己的本地模擬數據存儲區,除非被告知不要,這樣可以幫助堅持工人之間的工作狀態。

我假設你在任務隊列上離開任務並無限期地延長租期的技術意味着允許新工作人員拾取中斷工作,同時還避免多個工作人員執行相同的工作。對於無限任務,基於數據存儲構建類似的機制並使用保持活動進程根據需要重新啓動工作也可以。我很難爭辯說這會好得多,但它可能會簡化開發環境問題。

+0

感謝您的意見,我更新了我的問題和建議 – pfried