2011-05-24 15 views
5

Estoy creando una aplicación Java EE que permite a los usuarios agregar/eliminar tablas "socketinfo" (almacenadas en una base de datos) desde una interfaz web. Si el usuario habilita un "socketinfo" desde la interfaz web, el servidor de aplicaciones debe crear un escucha de socket para los paquetes entrantes y procesar los datos. Si el usuario deshabilita o elimina el "socketinfo", se debe eliminar el detector de socket. Todo el producto debe estar contenido en un solo oído y, preferiblemente, cumplir. Algunos enfoques he considerado, pero se topó con problemas son:Java EE: Creación y eliminación de receptores de socket dinámicamente desde el modelo de dominio

  1. Crear un adaptador de recursos JCA para sockets y utilizar BMD como los oyentes. El problema que me topé aquí fue que no puedo encontrar la forma de implementar mediante programación los MDB para diferentes sockets cuando el usuario los agrega.

  2. Cree un ejb @ @ Singleton/@ Service que gestione los hilos del daemon con una sincronización cuidadosa. El ejb singleton se puede inyectar en la capa empresarial para que las operaciones CRUD y la manipulación del socket sucedan en el flujo de trabajo correcto. El problema aquí fue que supuestamente la creación de subprocesos desde los EJB se considera una mala práctica y no cumple con las especificaciones (incluso si el ciclo de vida de singleton se maneja correctamente y existen mecanismos de sincronización adecuados).

  3. Coloque los hilos en el modelo de dominio (¿otro singleton?) Y haga que los EJB usen el modelo. Este fue el peor de todos, ya que los servidores de aplicaciones tienden a tener múltiples cargadores de clases, menos soporte de contenedores en general, además esto sufre de todo lo que 2. sufre.

¿Alguna idea de cómo manejar correctamente esta situación en Java EE?

EDIT: Una extensión de esta pregunta: Suponiendo que decida abordar este problema como sugiere ewernli en su solución 3, ¿qué gano al hacer esto en JCA (con una interfaz personalizada para agregar hilos internos) que no obtener de un singleton (bien diseñado)? Si bien la creación de un adaptador de recursos no parece una tarea monstruosa, no parece completamente trivial y podría consumir un poco de tiempo (y tal vez incluso más difícil de seguir para otros desarrolladores).

+0

¿Estoy leyendo esto correctamente? ¿Desea crear escuchas de socket, es decir ServerSockets en tiempo de ejecución desde un contenedor Java EE, y luego capturar y procesar los datos que llegan a los sockets de una manera predefinida? –

Respuesta

1

Su análisis parece razonable, y tiene razón cuando dice que no puede implementar MDB dinámicamente para que coincida con JCA.

pocos más ideas de diseño:

  • se podría escribir un conector JCA que devuelve SocketConnections (en el espíritu de JMS), que se puede utilizar para leer de un socket. Para continuar con la analogía de JMS, MDB representa MessageListener, mientras que lo que expondrías es MessageConsumer.

  • Puede usar un temporizador periódico para simular un hilo. En lugar de un hilo con un ciclo while, tiene un temporizador que se reprogramaba a sí mismo. Lo usé para una aplicación para tener un proceso en segundo plano, y funcionó bien. Tenga en cuenta que también generé hilos directamente desde los EJB para hacer algunos cálculos concurrentes en otra aplicación, y eso también funcionó bien. Pero los hilos de corta duración y el método comercial en el bean esperarían hasta que todo estuviera completo, de modo que no constituiría una violación importante de la especificación.

  • Otro diseño más tendría que hacer que el conector JCA maneje los hilos, etc. y entregue todos los mensajes a MDB. El MDB recibiría los datos, junto con la información sobre el "canal" al que corresponden los datos, p. el puerto de Socket Es como multiplexar todo en un MDB, que luego demultiplexa los datos.Su conector puede proporcionar una API adicional para controlar la creación de hilos, etc., y esta interfaz podría ser inyectada en su EJB (similar a ConnectionFactory). Su conector puede proporcionar API adicional para controlar la creación de subprocesos, etc. No es claro, pero espero que tenga la idea. Si estoy en lo cierto, el conector JCA puede asegurarse de entregar los datos sincrónicamente a MDB, al menos por socket, para que MDB procese los datos en el orden correcto.

me iría a # 3, si el tiempo lo permite el desarrollo.

EDITAR

Esta elección es de hecho parte una cuestión de la pureza de diseño. Sin embargo, un problema con los hilos distribuidos por el usuario es que obviamente no puede usar transacciones declarativas para ellos. Sin embargo, puede usar un UserTransaction para demarcar la transacción. No sé qué tan bien puede usar un EntityManager también en dicho hilo. Si procesa principalmente datos y no utiliza muchas funciones del middleware, puede lanzar hilos usted mismo. Ver otra respuesta mía: How can an EJB parallelize a long, CPU intensive process?. Otras cosas que me viene a la mente (no sé si son problemáticas o no): el administrador de seguridad puede evitar la creación de subprocesos (?), No crearlos, ya que deamon threads podría evitar la aplicación. el servidor se apaga correctamente (?). Tenga en cuenta que generé hilos de ServeletContextListener al inicio y que funcionó muy bien. Este es un truco empleado frecuentemente incluso si viola las especificaciones. Lo mismo podría suceder con los frijoles singleton "recién" introducidos. Por lo tanto, si tiene poco tiempo, por supuesto puede probar su proposición con un bean singleton y ver qué funciona/no funciona.

+0

Si pudiera explicar por qué 3 (ver edición de pregunta) estaría muy agradecido. – insipid

+0

@insipid done :) – ewernli

+0

Olvidé mencionar que también escribí el conector JCA de entrada y salida, y que también funciona bien, pero estoy de acuerdo, requiere algo de tiempo para familiarizarse con las especificaciones de JCA. – ewernli

1

Estoy bastante seguro de que # 2 es la mejor solución (y también es válida). No he mirado las especificaciones para los ejb nuevos de "Singleton" pero mi suposición es que el enrutamiento dentro de estos sería aceptable (considerando que es aceptable hacer su propia sincronización dentro de estos ejbs). estos se diseñaron para facilitar (p. ej.) la implementación de servicios de tipo de gestión, lo que se podía hacer previamente con JMX (aunque la implementación no estaba estandarizada). dentro de un mbean JMX, sin duda sería aceptable realizar su propia gestión de hilos, , así que lo transferiría a Singleton ejbs .

hizo una rápida revisión de la especificación ejb 3.1, y supongo que la única concesión para Singleton es el control de concurrencia, no threading/cosas de socket. tipo de tonto. Supongo que no son un reemplazo de mbean JMX completo. dicho esto, siempre puedes usar un mbean JMX, aunque la implementación no es estándar. si está utilizando jboss, entonces la anotación Service es equivalente a un mbean JMX, en el que todo debería ser permitido (hilos, conectores, etc.).

+0

Buen punto sobre la sincronización. No estoy seguro de que @Singleton beans estuviese destinado a administrar * a la * JMX. Yo diría que son una alternativa al caché y el uso de campos 'estáticos', lo que todos hacen, pero también viola las especificaciones. Pero tal vez @Service en JBoss (es específico de JBoss, ¿no?) Son ligeramente diferentes. Sin embargo, los subprocesos de usuario escapan a la gestión de transacciones del contenedor, lo que debe tenerse en cuenta, ver mi edición en mi respuesta. – ewernli

Cuestiones relacionadas