2009-08-04 7 views
2

En termes de performances JMS, j'ai lu que ObjectMessage doit être évité pour des raisons de performances.Performance JMS: BytesMessage vs ObjectMessage

À quel point les performances d'ObjectMessage sont-elles mauvaises? Devrais-je sérialiser vers un BytesMessage et désérialiser manuellement?

+1

Avez-vous rencontrez un problème? Avez-vous comparé les deux? Est-ce vraiment la partie la plus lente de votre application? –

+0

Non, je n'ai pas fait de benchmark. Je suis en train de réécrire une quantité significative de code et je ne voulais pas baisser la tête d'une seule méthode pour me rendre compte qu'il y avait un problème avec ça. Je voulais faire mes recherches en premier. Je suis tombé sur ce fil de 9 ans et je n'ai rien vu de plus récent: http://www.mail-archive.com/[email protected]/msg07681.html Espérait entendre quelque chose plus autoritaire. – Tazzy531

Répondre

8

La surcharge de performances de ObjectMessage est due au processus de sérialisation java.io. Si vous faites cela vous-même et utilisez ByteMessage, vous faites juste ce que JMS ferait lui-même, et vous ne serez pas mieux lotis.

Si vous devez envoyer des objets Java via JMS, vous devez utiliser ObjectMessage, c'est ce que fournit l'API. Ceci permet au conteneur de faire quelques optimisations, par ex. JBoss utilisera son propre protocole de sérialisation propriétaire, qui est considérablement plus rapide que le protocole standard java.io.

+0

C'est ce que j'ai pensé aussi ... – Tazzy531

+1

J'ai regardé la sérialisation de Hesse. Il semble sérialiser les objets à environ la moitié de l'espace en Java Serialization. Je n'ai pas encore fait de tests réels, mais il me semble que l'utilisation de + BytesMessage pourrait être avantageuse sur ObjectMessage dans ce cas. – Dave

+0

J'irais probablement avec JBoss Serialization sur Hessian/Burlap, mais en principe oui, il existe de meilleures alternatives à la sérialisation standard. – skaffman

1

Exemple avec Jackson sourire format de données qui peut être jusqu'à 50% plus rapide et plus petit que sérialisation JDK, donc BytesMessage dans ce cas va battre ObjectMessage:

import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.dataformat.smile.SmileFactory; 
import com.fasterxml.jackson.dataformat.smile.SmileGenerator; 
import org.springframework.jms.core.MessageCreator; 

import javax.jms.BytesMessage; 
import javax.jms.JMSException; 
import javax.jms.Message; 
import javax.jms.Session; 

public class BytesMessageCreator<T> implements MessageCreator 
{ 
    public static final ObjectMapper 
    MAPPER=new ObjectMapper(new SmileFactory().disable(SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT)); 

    final String messageId; 
    final T pojo; 

    public BytesMessageCreator(final T pojo) 
    { 
    messageId=null; 
    this.pojo=pojo; 
    } 

    public BytesMessageCreator(final String messageId, final T pojo) 
    { 
    this.messageId=messageId; 
    this.pojo=pojo; 
    } 

    @Override 
    public Message createMessage(final Session session) throws JMSException 
    { 
    try{ 
     final BytesMessage message=session.createBytesMessage(); 
     message.writeBytes(MAPPER.writeValueAsBytes(pojo)); 
     if(messageId != null){ 
     message.setJMSMessageID(messageId); 
     } 
     return message; 
    } catch(Exception e){ 
     throw new RuntimeException(e); 
    } 
    } 

}