Home > Desarrollo > Grails + JMS + Clustering en glassfish

Grails + JMS + Clustering en glassfish

September 30th, 2009 chechu Leave a comment Go to comments

Este post es una continuación de Grails + JMS + Email, donde se explicaba cómo configurar Grails 1.0.4 para que se enviaran emails mediante JMS. Una vez actualizado a Grails 1.2-M2 algunas de las cosas que comenté en su momento dejan de ser válidas.

Además se repasan los pasos básicos para definir un clúster en glassfish y se dan algunos consejos sobre aspectos a tener en cuenta y que pueden provocar errores dificilmente detectables.

Comencemos por las rectificaciones al post anterior:

  • No es necesario añadir returns en el código del plugin, tal cual viene compila perfectamente.
  • Deshabilitar el transactionManager se convierte en obligatorio al intentar desplegar la aplicación en un clúster de Glassfish. Al trabajar con un clúster de Glassfish las opciones para el broker JMS son tres: EMBEDDED, LOCAL y REMOTE.

    La opción EMBEDDED no tiene sentido (al menos yo no lo veo) si tenemos un clúster, ya que cada broker JMS se ejecutará en la JVM de cada instancia, perdiendo así la posibilidad de distribuir la carga que nos da JMS.

    La opción REMOTE nos obliga a gestionar por nuestra cuenta un broker JMS mientras que con la opción LOCAL el propio servidor gestiona (arranca y para) un broker, concretamente ejecuta el binario imqbrokerd que viene en la propia distribución de glassfish.

    Nuestra opción ha sido LOCAL, que es la opción por defecto al trabajar con clústers en glassfish. Este mensaje da la pista sobre un posible problema con las transacciones en la configuración LOCAL y recomienda deshabilitarlas. Así lo hice y funcionó perfectamente. Se deshabilita en la web de administración de Glassfish, al crear el JMS connection factory y también tenemos que eliminarlo en el plugin de JMS instalado en nuestra aplicación (fichero ~/.grails/1.2-M2/projects/[proyecto]/plugins/jms-0.5-RC2/src/groovy/grails/jms/listener/ListenerConfig.groovy, línea 125 en la versión 0.5-RC2)

  • Sobre los receptores de mensajes, hay que asegurarse de que el valor devuelto sea serializable y tener en cuenta que en groovy si se declara el método como def metodo... se devolverá el valor de la última sentencia ejecutada en el método. Para evitar problemas, podemos fijar el método como void.

Sobre los pasos a seguir para montar el clúster, podrían ser los siguientes:

  1. Crear el dominio: asadmin create-domain --profile cluster --portbase 5000 thuest.
  2. Crear el node-agent que gestionará la instancia: asadmin create-node-agent --port 5048 agent1
  3. Crear el clúster: ya en la consola Web, Clusters -> New. Indicamos un nombre y en la sección de instancias a ser creadas también seleccionamos New, asociando la nueva instancia al agente creado en el paso anterior. Al crear el clúster la instancia creada a la par será arrancada automáticamente. Cuando tengamos que aplicar nueva configuración es mejor parar y arrancar el clúster completo que cada instancia (de hecho al parar y arrancar una instancia individualemente te dará un error sobre operación no permitida).
  4. Aplicar configuración: parar y arrancar clúster (desde la consola web). Si deseamos parar y arrancar todo podemos usar la línea de comandos:
    • $> asadmin stop-node-agent agent1: para el agente agent1
    • $> asadmin stop-domain thuest: para el dominio thuest
    • $> killall java: a las bravas, mata todos los procesos java. Mucho cuidado porque esto afecta a procesos que a lo mejor no tienen nada que ver con glassfish
  5. Balanceo con mod_jk. Ver este enlace para hacerse una idea. Será necesario establecer una propiedad JVM, lo cual se hace a nivel de clúster: desde la consola Web ir a Configurations -> mycluster-config -> JVM Settings -> JVM Options y añadir esto: -Dcom.sun.enterprise.web.connector.enableJK=${WORKER_PORT}. Ahora, para cada instancia habrá que definir una propiedad WORKER_PORT que es el puerto configurado en el mod_jk para un worker. Eso se hace desde la consola Web: Clusters -> mycluster -> instance1 -> Properties. Una vez creada la propiedad reniciamos el clúster y comprobamos que podemos acceder a glassfish en el puerto 80 (que básicamente es lo que nos permite esto, además de poder conseguir un balanceo de carga si tienes varias instancias glassfish)
  6. Definir los recursos JMS y JDBC, teniendo cuidado con los nombres JNDI que les demos. Yo aconsejo no usar más de una / de indirección. Por ejemplo, jms/connectionFactoryThuest es preferible a jms/connectionFactory/thuest. Supongo que debe dar igual pero yo he sufrido algunos problemas inexplicables y seguir este consejo los solucionó. Además, asegurate de indicar el target correcto para cada recurso.
  7. Reinicia el clúster, el agente y el dominio todas las veces que hagan falta hasta asegurarte de que los recursos se ven por quien tienen que ser vistos. Mata procesos, elimina restos de despliegues anteriores y no te canses de empezar desde cero una y otra vez.

Son muchas pequeñas cosas, a lo mejor a ti no te afecta todo, pero nunca sobran cosas que repasar cuando algo va mal. Más adelante publicaré mi plan de despliegue de la aplicación, para que yo me acuerde y sirva de ayuda a quien la necesite.

Categories: Desarrollo Tags:
  1. No comments yet.
  1. No trackbacks yet.