我有一個Play
插件,執行每15分鐘這樣的方法:如何確保只有一個播放實例實際運行在一個特定時刻的方法
import scala.concurrent.Future
import scala.concurrent.duration._
import play.api.libs.concurrent.Akka
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.{Application, Plugin}
import akka.actor.Cancellable
class AuthPlugin(app: Application) extends Plugin {
private var cancellableDoSomething: Option[Cancellable] = None
...
override def onStart = {
cancellableDoSomething = Some(
Akka.system.scheduler.scheduleOnce(0.seconds) {
doSomething.foreach { _ =>
Akka.system.scheduler.scheduleOnce(15.minutes)(doSomething)
}
}
)
}
override def onStop = {
cancellableDoSomething.foreach(_.cancel)
}
}
object AuthPlugin {
...
def doSomething: Future[Unit] = {
// Access to shared DB here...
}
}
讓我們假設我有我的Play
兩個實例應用程序運行在兩臺不同的主機上,每臺主機每15分鐘調用一次doSomething
。
如何確保只有一個實例在某個特定時刻實際運行doSomething
?
編輯
兩個Play
實例訪問同一個數據庫,並doSomething
進程狀態pending
記錄。在處理完狀態爲pending
的記錄後,它會更新爲狀態processed
。
如果第一Play
實例查詢數據庫掛單並在處理他們的第二Play
實例中運行相同的查詢時,其獲得的是還包括掛起已經由第一Play
例如查詢訂單,但尚未處理的記錄集。爲避免這種情況,當且僅當沒有其他正在執行它的實例時,實例才能調用doSomething
。
我可以實現了一種基於DB-信號的地方獲取第一Play
例如,它字段的值設置爲1
或任何其他...但因爲如果Play
實例失敗這種解決方案並不穩定,從來沒有將字段設置爲0
,然後其他Play
實例不再能夠獲取信號量並調用doSomething
。
我假設你有一個共享資源問題。你能描述你想要達到的目標嗎? – Aaron
由於每個遊戲應用都運行在不同主機上的獨立JVM上,因此您有兩種選擇:使用某些外部服務進行同步或自行實現此類同步,例如在Akka – maks
的幫助下創建nfs數據庫機器共享創建文件並使用男人2在它上面 – ayvango