Слушать 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")) {
}