2011-10-16 15 views
10

Play框架的一大優點是它完全無狀態,只有請求/響應導向。這是非常好的,因爲它允許我將我的應用部署到雲中,並在負載均衡器後面擴展播放實例的數量,而無需擔心狀態(會話)複製...Play Framework:作業對無狀態模型的影響

但是,最近我需要在HTTP請求之外執行一些應用程序邏輯,並發現Play可以定義完全由框架管理的作業。聽起來很棒,但它提出了一個問題:這些工作如何適應Play所使用的無狀態模型?

說我有一個維護任務,需要每小時運行一次,併爲此定義一個計劃作業。如果我然後在負載平衡器後面部署多個Play實例,那麼每個實例會同時啓動該作業嗎?如果是這樣,那麼處理需要「專門」運行的工作的好方法是什麼?

我正在考慮在非集羣服務器上創建一個新的播放實例,重新使用現有(集羣)實例的JPA模型(從而連接到同一個數據庫)。這個新實例只包含維護作業,並且由於它託管在非集羣服務器上,所以不存在同時運行作業的風險。同時,這將允許我保持現有的羣集實例完全無狀態,並易於實現主機/負載均衡。這會是一個好方法嗎?

+0

開始賞金,見下文。 – ripper234

回答

5

我也會建議集羣工作。您可以在數據庫中設置信號量以確保只有一個作業正在運行。 另一個想法是看看Akka框架,它將包含在Play 2.0中。我認爲它已經建立了處理這個問題的機制,但我不確定。我沒有經歷過阿卡。

5

如上所述,在數據庫中保留一個標記有助於瞭解該作業是否已在運行。我使用其他標誌的db信號量給我工作狀態和額外的信息。

你可以做的另一件事是使用Play.id來制定和定義哪個實例應該運行作業。 我們用「玩開始 - %PROD」,「播放開始 - %PROD1」 ...以啓動應用程序,並在我的doJob以下()方法:


doJob(){ 
    if ("prod".equalsIgnoreCase(Play.id)) { 
    ... 
    } 
} 
+0

謝謝!我真的不喜歡爲此鎖定我的數據庫的想法,但我喜歡你的檢查工作正在運行的實例的建議! – stikkos

2

有過快速查看Play Framework的源代碼(類JobJobsPlugin)我認爲這些不適合在羣集環境中使用,因爲重要的是,作業僅在某個時間間隔內運行一次(不引入醜陋的黑客)。

我看到三個可能的解決方案:

  1. 使用支持集羣作業調度程序。明顯的選擇是Quartz。 Play還使用Quartz的零件(解析CRON表達式),但不使用調度的部分。

  2. 使用Play 2時,可能會去Akka,它提供a scheduler

  3. 改變你的工作,使它在運行兩次時無關緊要(可能適用於某些用例)。

+0

是的,我們正在考慮解決方案#1 – ripper234

相關問題