2012-10-01 18 views
5

Estoy diseñando una aplicación que se ejecutará en un contenedor OSGi (actualmente Equinox). Recibirá mensajes sobre RabbitMQ y los procesará internamente. La aplicación se ejecutará continuamente como un servidor. Mi plan actual es hacer que el paquete de escucha RabbitMQ configure sus colas y colocar escuchas en ellas, usando QueueingConsumer y ejecutándose en sus propios hilos. Los oyentes llamarían a uno o más servicios de procesamiento para manejar los mensajes. Los procesadores necesitan hacer llamadas JDBC para acceder a las bases de datos. Me gustaría poder controlar el orden en que se llaman los procesadores. Sería bueno tener la flexibilidad de agregar más servicios en un momento posterior sin tener que volver a codificar los oyentes RabbitMQ.Diseñando una aplicación OSGi de Java usando RabbitMQ mientras utilizo PreparedStatement

El problema que enfrento es que los mensajes pueden venir en ráfagas o lentamente. Me gustaría poder usar PreparedStatement para acelerar el acceso a la base de datos, pero tampoco quiero mantener las conexiones abiertas a largo plazo mientras no ocurra nada. He pensado en subclasificar DefaultConsumer directamente y dejar que se ejecute en los hilos en el RabbitMQ Connection, pero luego pierdo la capacidad de saber cuándo no está pasando nada. Mi idea original era mantener los procesadores de mensajes completamente separados como servicios OSGi, y tener cada uno una conexión de base de datos de un grupo de servidores cada vez que se llamaba, pero eso pierde la ventaja de las declaraciones preparadas. Estoy usando el conjunto JDBC de Tomcat, y no parece haber preparado el almacenamiento en caché de sentencias. Además, no estoy seguro de lo caro que sería crear una declaración preparada para cada llamada, pero parece un desperdicio.

La mejor idea que he encontrado hasta ahora es hacer que mis oyentes procesen en un doble ciclo. El bucle externo espera un mensaje, luego llama a un bucle interno que establece conexiones de base de datos y prepara declaraciones y ejecuta hasta que no ingresen más mensajes durante un tiempo de espera especificado, luego cierra sus conexiones y regresa al bucle externo. Lo hice funcionar para un solo proceso, pero tengo problemas para visualizar cómo administrar esto si tengo múltiples procesadores que pueden tener diferentes declaraciones preparadas.

Tal vez tenga que renunciar a la idea de múltiples servicios y codificar el procesamiento en mis oyentes.

¿Alguna sugerencia? ¡Gracias!

Respuesta

1

¿Por qué no utilizar los servicios como oyentes y pasarles la conexión JDBC que deberían usar? Una sola pieza de código luego envía las colas a sus servicios. Este despachador central puede mantener trivialmente un conjunto de conexiones JDBC preparadas. Si no desea ver la conexión JDBC en la API, use el servicio Coordinador para mantener una conexión. Los servicios "conscientes" pueden obtener la conexión JDBC optimizada.

O bien, registre un DataSource como servicio para su servicio de escucha e implemente su propia política de grupo. Como conoce a la persona que llama en una llamada de servicio OSGi, puede hacer todo tipo de optimizaciones, p. lee las declaraciones preparadas del paquete jar y las almacena en caché en consecuencia.

No me rendiría en los servicios aquí, el desacoplamiento que obtienes es excelente, lo sé por experiencia. Como en este modelo los oyentes del servicio no tienen dependencia de RabbitMQ, puede probarlos fácilmente y/o cambiar a otra tecnología de cola.

Por otra parte,, en estos casos lo mejor es hacer la solución más simple que se te pueda ocurrir. Si tiene un problema de rendimiento, mida y solucione los cuellos de botella. Se desperdicia una enorme cantidad de esfuerzo en soluciones prematuras ... Puedo contarle algunas tontas optimizaciones prematuras en las que he perdido el tiempo.

+0

Gracias. Soy prácticamente un novato OSGi, aprendiendo en la escuela de los golpes duros. No estoy familiarizado con el servicio de Coordinador, pero lo verificaré.Desde que publiqué esto, tuve la idea de registrar creadores de servicios en lugar de registrar servicios. La persona que llama puede usarlos para crear los servicios reales, lo que les permite crear sus declaraciones preparadas "justo a tiempo", usarlas durante ráfagas de actividad y cerrarlas cuando ocurre una pausa. –

+0

Revisé la versión de Equinox que estoy ejecutando, y no veo un servicio de Coordinador. ¿Hay algo especial que deba hacer para que funcione? Creo que estoy usando la versión 4 de la versión 4.3. –

+0

Creo que el * Servicio de Coordinador * se refiere al * "único fragmento de código [que] distribuye las colas a sus servicios" *. Nunca he oído hablar de ningún servicio OSGi estándar llamado * Coordinador *. –

Cuestiones relacionadas