2)消息体:JMS API定义了5种消息体格式,也叫消息类型,你可以使用不同形式发送接收数据并可以兼容现有的消息格式,下面描述这5种类型:
TextMessage:java.lang.String对象,如xml文件内容
MapMessage:名/值对的集合,名是String对象,值类型可以是Java任何基本类型
BytesMessage:字节流
StreamMessage:Java中的输入输出流
ObjectMessage:Java中的可序列化对象
Message:没有消息体,只有消息头和属性
3)消息可靠性
在上面谈及消息体格式定义中,有个字段JMSDeliveryMode用来表示该消息发送后,JMS提供商应该怎么处理消息。PERSISTENT(持久化)的消息在JMS服务器中持久化。接收端如果采用点对点的queue方式或者Durable Subscription(持久订阅者)方式,那么消息可保证只且只有一次被成功接收。NON_PERSISTENT(非持久化)的消息在JMS服务器关闭或宕机时,消息丢失。根据发送端和接收端采用的方式,列出如下可靠性表格,以作参考。
注意:以下的可靠性不包括JMS服务器由于资源关系,造成的消息不能持久化等因素引起的不可靠(该类不可靠应该是JMS提供商或硬件引起的的资源和处理能力的极限问题,应该由管理人员解决)。也不包括消息由于超时时间造成的销毁丢失。
消息发送端 消息接收端 可靠性及因素
PERSISTENT queue receiver/durable subscriber 消费一次且仅消费一次。可靠性最好,但是占用服务器资源比较多。
PERSISTENT non-durable subscriber 最多消费一次。这是由于non-durable subscriber决定的,如果消费端宕机或其他问题导致与JMS服务器断开连接,等下次再联上JMS服务器时消息不保留。
NON_PERSISTENT queue receiver/durable subscriber 最多消费一次。这是由于服务器的宕机会造成消息丢失
NON_PERSISTENT non-durable subscriber 最多消费一次。这是由于服务器的宕机造成消息丢失,也可能是由于non-durable subscriber的性质所决定
4)消息的优先级
虽然JMS规范并不需要JMS供应商实现消息的优先级路线,但是它需要递送加快的消息优先于普通级别的消息。JMS定义了从0到9的优先级路线级别,0是最低的优先级而9则是最高的。更特殊的是0到4是正常优先级的变化幅度,而5到9是加快的优先级的变化幅度。举例来说:
topicPublisher.publish (message, DeliveryMode.PERSISTENT, 8, 10000); //Pub-Sub
或 queueSender.send(message,DeliveryMode.PERSISTENT, 8, 10000);//P2P
这个代码片断,有两种消息模型,映射递送方式是持久的,优先级为加快型,生存周期是10000 (以毫秒度量)。如果生存周期设置为零,这则消息将永远不会过期。当消息需要时间限制否则将使其无效时,设置生存周期是有用的。
5)消息的通知确认
在客户端接收了消息之后,JMS服务怎样有效确认消息是否已经被客户端接收呢?
Session session=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
这段代码创建一个非事务性的session,并采用auto_acknowledge方式通知JMS服务器。如果采用事务性session时,通知会伴随session的commit/rollback同时发送通知。在我们采用非事务session时,有三种通知方式。
通知方式 效果
DUPS_OK_ACKNOWLEDGE session 延迟通知。如果JMS服务器宕机,会造成重复消息的情况。程序必须保证处理重复消息而不引起程序逻辑的混乱。
AUTO_ACKNOWLEDGE 当receive或MessageListener方法成功返回后自动通知。
CLIENT_ACKNOWLEDGE 客户端调用消息的acknowledge方法通知
5、PTP模型
点对点(Point- to-Point)消息传送使用的目标是队列。通过使用队列,消息可以被异步或同步地发送和接收。每一条到达队列的消息将会被投递到单独一个消费者一次,并且只有一次。这就好像两个人之间的邮件发送。消费者可以通过MessageConsumer.receive()方法同步地接收消息或使用 MessageConsumer.setMessageListener()方法注册一个MessageListener实现来异步地接收消息。队列保存所有的消息直到它们被投递出去或过期。
JMS PTP模型中的主要概念和对象:
Queue:由JMS Provider管理,队列由队列名识别,客户端可以通过JNDI接口用队列名得到一个队列对象。
TemporaryQueue:由QueueConnection创建,而且只能由创建它的QueueConnection使用。
QueueConnectionFactory:客户端用QueueConnectionFactory创建QueueConnection对象。
QueueConnection:一个到JMS PTP provider的连接,客户端可以用QueueConnection创建QueueSession来发送和接收消息。
QueueSession:提供一些方法创建QueueReceiver 、QueueSender、QueueBrowser和TemporaryQueue。如果在QueueSession关闭时,有一些消息已经被收到,但还没有被签收(acknowledged),那么,当接收者下次连接到相同的队列时,这些消息还会被再次接收。
QueueReceiver:客户端用QueueReceiver接收队列中的消息,如果用户在QueueReceiver中设定了消息选择条件,那么不符合条件的消息会留在队列中,不会被接收到。
QueueSender:客户端用QueueSender发送消息到队列。
QueueBrowser:客户端可以QueueBrowser浏览队列中的消息,但不会收走消息。
QueueRequestor:JMS提供QueueRequestor类简化消息的收发过程。QueueRequestor的构造函数有两个参数:QueueSession和queue,QueueRequestor通过创建一个临时队列来完成最终的收发消息请求。
可靠性(Reliability):队列可以长久地保存消息直到接收者收到消息。接收者不需要因为担心消息会丢失而时刻和队列保持激活的连接状态,充分体现了异步传输模式的优势。
可以看到,一个或多个生产者发送消息,消息m2先抵达了queue,然后m1也发出了,并一同存在于一个先进先出的queue里面。消费者也存在一个或多个,对queue里的消息进行消费。但一个消息只会被的一个消费者消费且仅消费一次。