java - Rendimiento JMS
weblogic message-queue (3)
Aquí están algunas partes relevantes de la especificación de jms :
sección 2.8 multihilo
JMS Object Supports Concurrent Use
Destination YES
ConnectionFactory YES
Connection YES
Session NO
MessageProducer NO
MessageConsumer NO
sección 4.4.14 Ejecución en serie del código de cliente
JMS no causa la ejecución concurrente de código de cliente a menos que un cliente lo solicite explícitamente. Una forma de hacerlo es definir que una sesión serializa toda la entrega asíncrona de mensajes.
Así que como ya hemos mencionado, reutiliza todo lo que puedas. Reutilice la fábrica de conexiones, la conexión y los destinos para todos los hilos. Para cada hilo reutilizamos consumidores y productores.
Si está reutilizando una conexión JMS, tenga en cuenta que el proveedor JMS multiplexará diferentes sesiones en esas conexiones. Por lo tanto, incluso si es seguro reutilizar las conexiones, puede ser más rápido crear una conexión para cada sesión que necesite.
Estoy teniendo un poco de problemas para entender JMS desde una perspectiva de rendimiento. Tenemos este código muy sencillo en nuestra aplicación:
QueueConnection connection = null;
QueueSession session = null;
QueueSender sender = null;
TextMessage msg = null;
try {
// The JNDIHelper uses InitialContext to look up things
QueueConnectionFactory qcf = JNDIHelper.lookupFactory();
Queue destQueue = JNDIHelper.lookupQueue();
// These objects are created for every message, which is quite slow
connection = qcf.createQueueConnection();
session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
sender = session.createSender(destQueue);
// This is the actual message
msg = session.createTextMessage(xmlMsg);
sender.setTimeToLive(0);
sender.send(msg);
}
finally {
// Close all objects again
JMSUtilities.safeClose(sender);
JMSUtilities.safeClose(session);
JMSUtilities.safeClose(connection);
}
El código es correcto, pero probablemente algunos de los artefactos anteriores podrían reutilizarse para varios mensajes. Estas son nuestras configuraciones:
- Utilizamos Oracle Weblogic 10.3.3
- Weblogic se conecta a IBM MQ 7.0 (el problema también aparece con 6.0) para JMS
- La lógica anterior es ejecutada por un solo hilo en un servidor backend. Sería sencillo mantener algunos objetos (
QueueConnection
,QueueSession
,QueueSender
) en la memoria, ya que no hay concurrencia involucrada.
Mis preguntas
- ¿Qué tipos de objetos se pueden compartir entre varios mensajes? (por supuesto, incluiríamos la recuperación de errores, restaurar esos objetos compartidos)
- ¿Cuáles son las mejores prácticas para mejorar el rendimiento?
Lo único que necesita crear una y otra vez es el propio mensaje, si está enviando a la misma cola.
Así que sí, puedes recordar la conexión, la sesión y el remitente.
Definir "para compartir" .
Si quieres compartir entre diferentes hilos esto es muy peligroso. Puede compartir de forma segura el objeto QueueConnectionFactory, así como el objeto de conexión JMS. No debe compartir objetos de sesión, remitente / consumidor o mensaje. Así es como funciona TIBCO EMS. No estoy seguro de la plataforma de IBM, pero creo que esto es lo mismo.
Si puede estar seguro de que su método de "envío" no es llamado por diferentes hilos , puede encapsularlo en una clase de MySender con variables de miembro de Conexión, Sesión y Remitente. ¡Pero cuidado! Cierre correctamente los recursos en la salida. Eso es lo que recomienda Heiko Rupp. Algo así:
class MySender {
private QueueConnection connection = null;
private QueueSession session = null;
private QueueSender sender = null;
public MySender(...) { /* initialize conn/sess/sender */ }
public send(String xmlMsg) { /* sender.send(session.createTextMessage(xmlMsg)) */ }
public close() { /* close all resources */ }
}
Respecto al rendimiento. No hay mucho espacio para mejorar en el estándar JMS. Mantenga los mensajes pequeños y optimice la configuración del servidor. Utilice destinos duraderos solo cuando lo necesite, etc. Lea la documentación de su plataforma. Pero en el lado del cliente no hay mucho espacio. Algunas plataformas ofrecen funciones adicionales para JMS que permiten un aumento adicional del rendimiento (envíos por lotes, etc.) pero depende de la plataforma. No sé IBM.