一,消息的确认模式:
JMS API中约定了Client端可以使用四种ACK_MODE,在javax.jms.Session接口中:
- AUTO_ACKNOWLEDGE = 1 自动确认
- CLIENT_ACKNOWLEDGE = 2 客户端手动确认
- DUPS_OK_ACKNOWLEDGE = 3 自动批量确认
- SESSION_TRANSACTED = 0 事务提交并确认
此外AcitveMQ补充了一个自定义的ACK_MODE:
- INDIVIDUAL_ACKNOWLEDGE = 4 单条消息确认
我们在开发JMS应用程序的时候,会经常使用到上述ACK_MODE,其中"INDIVIDUAL_ACKNOWLEDGE "只有ActiveMQ支持,当然开发者也可以使用它. ACK_MODE描述了Consumer与broker确认消息的方式(时机),比如当消息被Consumer接收之后,Consumer将在何时确认消息。对于broker而言,只有接收到ACK指令,才会认为消息被正确的接收或者处理成功了,通过ACK,可以在consumer与Broker之间建立一种简单的“担保”机制.
我们需要在创建Session时指定ACK_MODE,由此可见,ACK_MODE将是session共享的,意味着一个session下所有的 consumer都使用同一种ACK_MODE。在创建Session时,开发者不能指定除ACK_MODE列表之外的其他值.如果此session为事务类型,用户指定的ACK_MODE将被忽略,而强制使用"SESSION_TRANSACTED"类型;如果session非事务类型时,也将不能将 ACK_MODE设定为"SESSION_TRANSACTED",毕竟这是相悖的.
二,事物类型
事务用来描述"一系列消息要么全部确认成功,要么全不确认"的特征,它和数据库事务最终需要达成的效果是一样的.JMS Provider会缓存每个生产者当前事务下的所有消息,直到commit或者rollback.commit操作将会导致事务中所有的消息被持久存储;rollback意味着JMS Provider将会清除此事务下所有的消息记录...在事务未提交之前,消息是不会被持久存储的,也不会被消费者消费.
每次事务提交之后,在client端会生成一个事务ID(一个session中不会出现重复的ID,clientID:sessionID:txID);事务的提交或者回滚都会携带ID.对于producer而言,在事务类型的session中,发送消息(一个或者多个)之后,需要执行session.commit(),否则消息将不会被存储.对于consumer而言,消息接收到之后,需要手动的使用commit,否则JMS Provider会认为消息没有被接收,导致重发,因此你可以认为commit就是一个消息确认操作.
三,消费消息的风格
Consumer消费消息的风格有2种: 同步/异步..使用consumer.receive()就是同步,使用messageListener就是异步;在同一个consumer中,我们不能使用使用这2种风格,比如在使用listener的情况下,当调用receive()方法将会获得一个Exception
四 指定消息传送模式
ActiveMQ 支持两种消息传送模式:PERSISTENT 和NON_PERSISTENT 两种。
1.PERSISTENT(持久性消息)
这是 ActiveMQ 的默认传送模式,此模式保证这些消息只被传送一次和成
功使用一次。对于这些消息,可靠性是优先考虑的因素。可靠性的另一个重要方面是确
保持久性消息传送至目标后,消息服务在向消费者传送它们之前不会丢失这些消息。这
意味着在持久性消息传送至目标时,消息服务将其放入持久性数据存储。如果消息服务
由于某种原因导致失败,它可以恢复此消息并将此消息传送至相应的消费者。虽然这样
增加了消息传送的开销,但却增加了可靠性。
2.NON_PERSISTENT(非持久性消息)
保证这些消息最多被传送一次。对于这些消息,可靠性并非主要的考虑因素。
此模式并不要求持久性的数据存储,也不保证消息服务由于某种原因导致失败后消息不
会丢失。
参考http://blog.csdn.net/suncaishen/article/details/6883856:
http://shift-alt-ctrl.iteye.com/blog/1923154
http://javavsnet.iteye.com/blog/1972523
http://shift-alt-ctrl.iteye.com/blog/2020182