java消息服务学习之JMS高级特性
将介绍的内容是: 控制消息确认、为发送消息指定选项、创建临时目的地、使用JMS本地事务、异步发送消息 五个方面。
1.控制消息确认
在JMS消息得到确认之前,并不认为它已经成功使用。要成功使用消息,通常分为三个阶段:
(1)、客户端接收消息。
(2)、客户端处理消息。
(3)、消息得到确认。确认可能由JMS提供者发出、或者由客户端发出、这取决于会话确认模式。
在本地事务性会话中,会话提交时消息就会得到确认。如果一个事务回滚,则已使用的所有消息都会重新发送。
在非事务性会话中。消息何时确认,以及如何确认取决于一个值。这个值可能作为createContext方法(JDK定义的接口为: public abstract JMSContext createContext(int i);)的一个参数来指定。可能的参数值为:
JMSContext.AUTO_ACKNOWLEDGE:这是应用客户端和java SE客户端默认设置。客户端成功地从一个receive调用返回时或者用来处理消息所调用的MessageListener成功返回时,JMS会自动确认客户端接收到一个消息。
JMSContext.CLIENT_ACKNOWLEDGE :客户端通过调用acknowledge方法来确认一个消息,通过这种模式,确认在会话级发生。确认使用了一个消息,也就自动确认了会话所使用的所用消息都都已经接收。例如,一个消息消费者消费了10个消息,然后对发送的第5个消息进行了确认,那么所有消息都得到了确认。
JMSContext.DUPS_OK_ACKNOWLEDGE:指示JMSContext采用懒惰方式确认消息的传送。如果JMS提供者失败,这很可能导致传送了一些重复消息,所以只有可以容忍重复消息的消费者才能使用这个模式,(如果JMS提供者传送了一个消息,就必须将JMSRedelivered消息首部的值设置为true。)这个选项可以尽量会话为避免重复所做的工作,从而降低会话开销。
2.为指定消息发送选项
发送消息时可以设置很多选项,利用这些选项可以完成以下任务:
指定消息持久化,这意味着即使提供者失败,消息也不会丢失。
指定消息的优先级,这会影响传送消息的顺序。
为消息指定一个到期时间,保证如果消息到期就不再传送。
为消息指定一个传送延迟,使消息在经过一个指定的时间之后才会传送。
使用JMSProducer方法串链
(1)、指定消息持久化
使用JMSProducer接口的setDeliveryMode方法,为这个生产者发送的所有消息设置传送模式。
模式有两种:
PERSISTENT:(这是默认的传送方式)这种模式是JMS提供者在消息提供的过程中即使JMS提供者失败,消息也不会丢失。采用这种模式发送消息,消息在发送时会存储到一个指定的位置。
NON_PERSISTENT:传送模式不要求JMS提供者存储消息,也不用保证提供者失败时消息不丢失
如果没有指定传送模式,则默认指定模式是PERSISTENT。使用NON_PERSISTENT传送模式可以提高性能,减少存储开销,不过只有当应用能够允许应用丢失消息时才能使用这个模式。
JDK中DeliveryMode接口关于这两个模式定义:
(2)、设置消息优先级
使用消息优先级指示JMS消息提供者先发送紧急的消息,使用JMSProducer接口的setPriority方法来为这个生产者所发送的所有消息来设置优先级。JDK源码为 (参数是毫秒)
优先级总共有十个级别从0到9逐渐增高,默认级别是4,JMS提供者会尝试优先传送高优先级的消息,然后再传送低优先级消息,不过并不一定按照优先级顺序来传送消息,类似java并发中的优先级规则。
(3)、允许消息到期
默认的消息永远不会到期,不过一个消息再指定的一段时间后过期,则可能希望设置一个到期时间,使用JMSProducer接口中的setTimeToLive方法来为这个生产者所发送的所有消息设置一个默认的到期时间。
发送消息时会将指定的setTimeToLive加上当前时间来得到到期时间,在指定的到期时间之前未能及时传送的所有消息将被撤销。撤销过期的消息可以节省存储空间和计算资源。
(4)、指定传送延迟
使用JMSProducer接口中的setDeliveryDelay方法为这个生产者所发送的所有消息设置一个传送延迟。即指定一个消息发送之后并在JMS提供者传送这个消息之前所要经过的时间。说白点即是给生产者设置个延迟时间,让它等准备完之后过一个延迟时间再发送。
(5)、使用JMSProducer方法串链
JMS接口的设置方法会返回JMSProducer对象,可以使用方法串链来创建一个生产者,设置多个属性,然后发送一个消息。
3.创建临时目的地
创建临时目的地(TemporaryQueue和TemporaryTopic对象),使用JMSContext.createTemporaryQueue和JMSContext .createTemporaryTopic方法动态地创建这些临时目的地,它们的存在时间只限于创建它们的连接所保持的时间。只有创建该临时目的地的连接上的消息消费者才能够从临时目的地中提取消息。任何消息生产者都可以向临时目的地发送消息,如果关闭了一个临时目的地的连接,这个目的地也会关闭,它的内容会丢失。
4.使用JMS本地事务
事务是将一系列操作分组到一个原子工作单元中。如果任意一个操作丢失,整个事务就会回滚,这些操作可能会从头重新执行。如果所有操作都成功,事务就可以提交。
在一个应用客户端或Java SE客户端中,可以使用本地事务对消息发送和接收分组。使用JMSContext.commit方法来提交事务。一个事务可以发送多个消息,在事务提交之前,这些消息不会真正增加到队列或主题。如果一个事务中接收多个消息,则事务提交之前不会得到确认。
使用JMSContext.rollback方法回滚一个事务。事务回滚意味着所有消息都被撤销,所有已经使用的消息会恢复并重新传送,除非它们已经到期。
消息的生产和消费不能包含在同一个事务中。
5.异步发送消息
发送一个持久化消息时,send方法会阻塞,直到JMS消息提供者确认这个消息已经成功发送。异步发送机制则允许应用发送一个消息,在等待发送是否完成的同时,可以继续完成自动自己的工作。
异步发送一个消息需要一个回调对象。利用CompletionListener实例化一个listener监听器对象,进行对发送的消息一直监听,如果消息发送失败,则调用OnException方法,如果消息发送成功,则调用OnCompletion方法 。CompletionListener类必须实现OnException和OnCompletion方法。
参考《Java EE 权威指南 卷2》