2011-10-16 6 views
10

Una de las mejores cosas del marco de juego es que es totalmente sin estado y solo está orientado a la solicitud/respuesta. Esto es realmente bueno ya que me permite implementar mi aplicación en la nube y escalar el número de instancias de reproducción detrás de mi balanceador de carga sin tener que preocuparme por la replicación de estado (sesión) ...Marco de juego: impacto de los trabajos en el modelo sin estado

Recientemente, sin embargo, necesitaba ejecute alguna lógica de aplicación fuera de una solicitud HTTP y descubra que Play tiene la posibilidad de definir trabajos que están totalmente gestionados por el marco. Suena genial, pero plantea la pregunta: ¿cómo encajan estos trabajos en el modelo sin estado que usa Play?

Supongamos que tengo una tarea de mantenimiento que debe ejecutarse cada hora y defino un trabajo programado para eso. Si luego despliego varias instancias de Play detrás de un equilibrador de carga, ¿ese trabajo se iniciará al mismo tiempo en cada instancia? Y si es así, ¿cuál sería un buen enfoque para manejar trabajos que deben ejecutarse "exclusivamente"?

Estaba pensando en crear una nueva instancia de reproducción en un servidor no agrupado, reutilizando el modelo JPA de la instancia existente (en clúster) (y, por lo tanto, conectando a la misma base de datos). Esta nueva instancia contendría solo los trabajos de mantenimiento y, dado que está alojada en un servidor no agrupado, no existe el riesgo de que un trabajo se ejecute simultáneamente. Al mismo tiempo, esto me permitiría mantener mi instancia agrupada existente completamente apátrida y fácil de mantener/equilibrar de carga. ¿Sería este un buen enfoque?

+0

Comenzando una recompensa, consulte a continuación. – ripper234

Respuesta

5

Yo recomendaría agrupar el trabajo también. Puede establecer un semáforo en la base de datos para asegurarse de que solo se está ejecutando un trabajo. Otra idea es echar un vistazo a Akka-Framework, que se incluirá en Play 2.0. Creo que tiene un mecanismo integrado para manejar este problema, pero no estoy seguro. No tengo experiencias con akka.

5

Como neils mencionó mantener un indicador en el DB ayuda a averiguar si el trabajo ya se está ejecutando. Uso un semáforo db con otros indicadores para darme el estado del trabajo y la información adicional.

Otra cosa que podría hacer es usar Play.id para calcular y definir qué instancia debe ejecutar los trabajos. Utilizamos "jugar de inicio -% prod", "inicio juego -% prod1" ... para iniciar las aplicaciones y el método() siguiente en mi doJob:


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

Gracias!Realmente no me gusta la idea de bloquear mi base de datos para esto, pero me gusta su sugerencia de comprobar en qué instancia se está ejecutando el trabajo. – stikkos

2

Habiendo obtenido un rápido vistazo en el código fuente de Play Framework (clases Job y JobsPlugin). Creo que estos no son adecuados para usar en un entorno de clúster cuando es importante que el trabajo solo se ejecute una vez por cada intervalo de tiempo (sin introducción de feos hacks).

veo tres posibles soluciones:

  1. utilizar un planificador de tareas que soporta la agrupación. La opción obvia es Quartz. Play también usa partes de Quartz (para analizar las expresiones CRON), pero no la parte que hace la programación.

  2. Al usar Play 2, posiblemente vaya a Akka, que ofrece a scheduler.

  3. Cambie su trabajo de modo que no importe cuando se ejecuta dos veces (posible en algunos casos de uso).

+0

Sí, estamos pensando en la solución n. ° 1 – ripper234

Cuestiones relacionadas