JMS性能:BytesMessage与ObjectMessage

时间:2009-08-04 13:50:50

标签: java serialization jms

就JMS性能而言,我已经读过,出于性能原因应该避免使用ObjectMessage。

ObjectMessage在性能方面有多糟糕? 我应该序列化为BytesMessage并手动反序列化吗?

2 个答案:

答案 0 :(得分:9)

ObjectMessage的性能开销是由于java.io序列化过程造成的。如果你自己这样做并使用ByteMessage,那么你就是在做JMS自己做的事情,而且你也不会更好。

如果需要通过JMS发送java对象,则应使用ObjectMessage,这就是API提供的内容。这允许容器进行一些优化,例如, JBoss将使用自己专有的序列化协议,该协议比标准java.io协议快得多。

答案 1 :(得分:1)

使用Jackson Smile数据格式的示例可以比JDK序列化快50%并且小于JDK序列化,因此在这种情况下BytesMessage将胜过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);
    }
  }

}