2011-08-17 11 views
7

Actualmente estoy trabajando en la función de limitación de ancho de banda (no me pregunte por qué, no es mi decisión) para aplicaciones que usan JMS (Spring framework JMS y Active MQ) para enviar mensajes con payload entre servidor y clientela.Tamaño de mensaje JMS

Encontré muchos métodos de aceleración para limitar los mensajes JMS entrantes (pero ninguno de ellos se basa en la carga de ancho de banda real), sin embargo, no encontré ninguna forma posible de limitar el flujo de mensajes salientes. Así que decidí escribir Leaky bucket algorithm por mi cuenta.

¿Hay alguna forma de obtener el tamaño del mensaje JMS? Aparte de aplicación 'sizeof' en Java (In Java, what is the best way to determine the size of an object?)

+0

Por qué no limitar el flujo de mensajes entrantes sería suficiente, lo que ActiveMQ le permite hacer con el uso de producerFlowControl y memoryLimits en los destinos. Tengo curiosidad por saber por qué querrías limitar los mensajes salientes también. Además, ¿no sería mejor controlar este tipo de cosas desde algún tipo de controlador de entrega de aplicaciones que se encuentre frente a su intermediario (suponiendo que incluso tenga esa opción)? – whaley

+0

Nuestro cliente desea limitar el ancho de banda saliente de los productores (digamos que el cliente tiene un ancho de banda de 100 mbit, pero quiere usar solo 10 mbit). Me vuelve loco. JMS está hecho para entregar mensajes lo antes posible, así que realmente no entiendo esa demanda. Pero lamentablemente no está en mi decisión. – Sorceror

Respuesta

3

Como los mensajes JMS se serializan en el proceso de envío, la mejor forma de obtener el tamaño del mensaje es through ObjectOutputStream.

private int getMessageSizeInBytes(MessageWrapper message) throws IOException { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    ObjectOutputStream oos = new ObjectOutputStream(baos); 
    oos.writeObject(message); 
    oos.close(); 
    return baos.size(); 
} 
4

no creo que usted tiene cualquier seriamente mejor alternativa para determinar el tamaño del mensaje JMS que la medición de su tamaño serializado.

Pero puede agregar algunas optimizaciones si lo desea. Hay varios tipos de mensajes (por ejemplo, MapMessage, ObjectMessage, TextMessage).

El tamaño del mensaje de texto es la longitud de su texto. El tamaño del mensaje del mapa es el tamaño total de todos sus campos. Los campos son primitivos o java.util.Date, por lo que no es un problema medirlos. El mensaje de objeto contiene un objeto serializable, por lo que puede medir su tamaño escribiendo a ByteOutputStream.

Creo que la implementación del cubo con fugas utilizando JMS se puede simplificar si está utilizando la función oculta de la mayoría de los proveedores de JMS para enviar mensajes con demoras. Puede medir el mensaje al enrutarlo y decidir cuándo desea que el suscriptor lo reciba. Lea aquí para más detalles de cómo enviar mensajes retrasados: http://alexradzin.blogspot.com/2010/10/send-delayed-jms-messages.html

+0

+1 para tener una buena idea para pensar, gracias .. – Sorceror

1

Además del comentario anterior por @AlexR, BytesMessage tiene un método getBodyLength()

http://download.oracle.com/javaee/1.4/api/javax/jms/BytesMessage.html#getBodyLength

y es probable que pueda estimar típica tamaño del encabezado en tránsito mediante la captura de algunos objetos creados con Session.createMessage(), es decir, el tipo de mensaje JMS sin carga. Creo que estaría tentado de trabajar directamente con una carga útil en un byte [], usar un BytesMessage y comprimirlo a través de ZipOutputStream si el ancho de banda es crítico. Además, JMS permite sugerencias para suprimir la marca de tiempo del mensaje y la identificación del mensaje, lo que puede ayudar a reducir el tamaño del mensaje, p.

http://download.oracle.com/javaee/1.4/api/javax/jms/MessageProducer.html#setDisableMessageTimestamp%28boolean%29

aunque no se requiere que los proveedores que lo soporte,

Si el proveedor de JMS acepta esta sugerencia, estos mensajes debe tener el ID de mensaje como nulas; si el proveedor hace caso omiso de la pista, el ID de mensaje debe ser ajustado a su valor único normales

vez que trabajé con JMS ancho de banda limitado mismos en WebSphere MQ Everyplace, y era posible obtener el tamaño del mensaje bastante pequeña en De esta manera, aunque el formato de wireframe nativo también se optimizó para el tamaño en ese caso

+0

El ancho de banda no es crítico, nuestro cliente solo desea administrar el rendimiento. +1 para 'getBodyLength()', pero tengo miedo de que esto funcione solo para las instancias 'BytesMessage', que supongo que no tengo ... – Sorceror

Cuestiones relacionadas