Un problema común en aplicaciones web surge a la hora de ejecutar trabajos en ciertos intervalos de tiempo desde una aplicación web. Hay varias opciones, pero cada una de ellas presenta ciertos inconvenientes:
java.util.Timer: Es una solución problemática ya que crea hilos fuera del dominio del servidor de aplicaciones, lo que podría ocasionar problemas potenciales.
Utilizar frameworks como quartz: Estamos en el mismo caso de antes. Estos frameworks toman el control y crean sus propios hilos. Esto no tiene que ser un problema cuando tú distribuyes tu producto (pues por ejemplo jLibrary utiliza quartz), pero sí lo es cuando tienes que meter una aplicación web en un servidor de terceros.
Utilizar un EJB de Timer: Es una solución. Pero requiere EJB 2.1, y por lo tanto J2EE 1.4, y todavía hay demasiados entornos con J2EE 1.3. El requisito de un EJB también te obliga a utilizar un servidor de aplicaciones completo.
Utilizar el WorkManager de JCA 1.5: Requiere J2EE 1.4 y te obliga a utilizar un servidor de aplicaciones completo.
Utilizar el API commonj (Timer and Work Manager for Application Servers): La verdad es que es una de las opciones más interesantes. Lo malo es que esta especificación del 2003, se retrasa y se retrasa. Por ahora sólo la soportan Weblogic 9 y WebSphere 6, así que tampoco hay mucho que hablar. A ver si se extiende porque es muy interesante y útil.
Utilizar un MBean de Timer con JMX: Esta es una solución interesante. Todo servidor compatible con JMX (es decir, cualquier servidor J2EE) está obligado a ofrecer un servicio de temporización sobre el que se pueden ejecutar trabajos. De este modo, tú puedes registrar ahí un MBean que se invocará regularmente y que notificará a tus clases el que se ha producido un evento. El problema es que en clusters, el modo de ejecución depende de como se implemente internamente el servicio de JMX en el servidor de aplicaciones. Quiero decir, ¿se ejecutará una única vez en una única máquina?,¿se ejecutará el trabajo en todas las máquinas?,¿tienes que atacar al servicio de JMX en algún modo concreto?, etc...
Otro servlet: La solución más trivial es crear otro Servlet que realize la tarea periódica y tener un proceso externo que llame periódicamente a ese Servlet. El problema es que en el entorno de despliegue tienen que admitir que les instales un servicio, o algo similar, cosa que no siempre se puede admitir.
¿Alguna solución más? ( Por cierto si alguien está interesado en la solución con JMX, podría publicarla ).
| Permalink Comentarios [6] |
Yo utilizo quartz corriendo dentro de un weblogic, no es la solucion mas elegante debido a que este maneja sus propios therad pero funciona.
Tambien utilizamos los servicios de Timer de JMX dentro de tomcat, pero no teniamos toda la flexibilidad y versatilidad de quartz.
Enviado por Diego en September 26, 2005 a las 09:21 AM EDT #
Martin...
Quiza lo que estoy haciendo no sea lo correcto, pero bueno, aprovecho que has tocado el tema ;P
Lo que hago es poner con un SetupServlet a nivel application un objeto ( extends Thread) que se encarga de realizar la tarea cada cierto tiempo.
Y funciona de maravilla!!!
El problema es que cuando detengo el server ... el hilo sigue vivo :( a pesar de que hago todo lo necesario para detener el hilo en el destroy() del SetupServlet.
Aun no logro saber porque ocurre eso, pero una vez solucionado, creo que es la mejor manera de realizar una tarea periodicamente.
Enviado por RuGI en September 26, 2005 a las 11:33 AM EDT #
Diego, a mi quartz también me parece una excelente librerÃa, de hecho en jlibrary, lo distribuyo, porque es un producto final. El problema es cuando tienes que desplegar cosas en un servidor de aplicaciones que no es tuyo, que no controlas, o que en un futuro puede que no controles.
En esos casos (y extiendo los comentarios a Rugi) no te puedes permitir hacer esas cosas, salvo con consentimiento explÃcito del cliente, ya que ¿qué sucede si uno de esos hilos ocupa el 100% de CPU?, ¿y si comienza a consumir demasiada memoria?, ¿y si se produce un halt en la máquina virtual? ... En un entorno gestionado pierdes flexibilidad pero ganas en seguridad.
Enviado por martin en September 26, 2005 a las 04:19 PM EDT #
En los diferentes desarrollos que he realizado, tanto en insufribles Windows como en entornos Unix he realizado lo que comentas con tareas externas que ejecutan procesos (casi siempre un servlet) en el servidor de aplicaciones de manera gestionada.
Tanto el cron como el programador de tareas de Windows (salvado las distancias) me ha valido perfectamente para procesos recurrentes sencillos y siendo objetivos no creo que la gran mayoria de desarrollos necesiten mas. Enough is enough.
De hecho aun entendiendo y habiendo experimentado las dudas que presentas en el segundo comentario y aceptando que obviamente el entorno de quartz y el de la webapp no sean el mismo, no creo que esto introduzca una debilidad _per se_ puesto que la libreria sigue corriendo en un entorno tan seguro como seamos capaces de configurarlo y crearlo. La seguridad de los Servlet Container tampoco es magia.
De hecho segun estoy escribiendo esto no creo que hubiera ningun problema en escribir un wrapper que funcionase como mini-servidor-de-tiempo para lo procesos de quartz y que funcionase de manera similar a un JMX casero y a la medida.
Un saludo
Enviado por Aitor GarcÃÂa en September 26, 2005 a las 04:47 PM EDT #
Aitor, al final, la solucion escogida va a ser lo que comentas, cron/servicios de windows + proceso que llama a un servlet.
Y bueno, respecto a los servidores, que le vas a hacer, hay un marco de legalidad (frase de moda) impuesto por los servidores de aplicaciones (por las razones que sea), y es suficiente para que en muchos sitios se obligue a respetarlo. Yo tambien estoy seguro de que con quartz se podrÃa hacer algo sólido perfectamente.
Enviado por martin en September 27, 2005 a las 02:05 AM EDT #
El problema con las soluciones caseras es que se pierde mucho tiempo en su desarrollo, mantenimiento y sobre todo si se quiere que se tengan features de alta disponibilidad, clustering, management, etc, se hace un poco complicado.
Creo que el quartz es una buena solucion ahora, pero tambien creo que en el futuro se utilizaran soluciones que vengan dentro de la especificicion como ser Timer de EJB o JSR 237: Work Manager for Application Servers (http://www.devx.com/Java/Article/28815)
Enviado por Diego en September 28, 2005 a las 04:32 PM EDT #