Слушать 2 запуска Heroku с несколькими динамо

У меня есть приложение Play 2.x, запущенное на Heroku с одним веб-динамо.

При запуске запускается актер Akka, который сам планирует будущие задания (например, отправка push-уведомлений).

object Global extends GlobalSettings {

  override def onStart(app:Application) {
    val actor = Akka.system.actorOf(Props[SomeActor])
    Akka.system.scheduler.scheduleOnce(0 seconds, actor, None)
  }
}

Это хорошо работает с одним веб-динамо, но мне любопытно узнать, что произойдет, если я увеличу количество веб-динамов. Будет ли onStart выполняться дважды с двумя веб-динамо?

Было бы замечательно, если бы Global действительно работал глобально, а onStart выполняется только один раз, независимо от количества веб-динамов. Если нет, несколько динамовцев должны каким-то образом договориться о том, чтобы один династер отвечал за работу.

Кто-нибудь сталкивался с подобной проблемой?

2 ответа

Решение

Если вы запустите два веб-динамометра, ваш глобальный будет выполнен дважды. Глобальный глобален для процесса. Когда вы масштабируете свой веб-процесс, вы запускаете два процесса. У вас есть пара вариантов:

  • Используйте другой процесс (он же одноэтапный процесс) для запуска вашего глобального. Хорошая особенность Play в том, что вы можете иметь несколько GlobalSettings Реализации. Когда вы начинаете свой процесс, вы указываете глобальный, который вы хотите использовать с -Dapplication.global=YourSecondGlobal, В вашем профиле вы бы singleton: target/start -Dhttp.port=${PORT} ${JAVA_OPTS} -Dapplication.global=YourSecondGlobal, Запустите ваши веб-процессы и singleton обработать и убедиться singleton масштабируется до 1.
  • Используйте распределенную семафору, чтобы получить блокировку. Затем каждый процесс будет стремиться получить блокировку - тот, который победит, продолжится, а остальные потерпят неудачу. Если вы используете Postgres (как и многие другие пользователи Heroku), рекомендательный замок - хороший выбор.

Вы также можете получить имя dyno во время выполнения:

String dyno = System.getenv("DYNO");

такая проверка может также сработать:

if(dyno.equals("web.1")) {

}
Другие вопросы по тегам