消息的签收是消息被消费的标志,消息的签收机制一定程度上来说是为了避免消息的重复消费问题,因此消息的签收偏重于消费者,对生产者几乎是没有意义,因为生产者不涉及到签收。
签收对消息的影响:
- 对于queue中的消息而言,一旦消息被签收则这条消息的状态就会从待消费状态(Pending Messages )变为已消费状态(Messages Dequeued )而从待消费队列中移除。
- 对于Topic中的消息而言,若采用MessageConsumer的消费模式则消息的签收机制是没有任何意义的,因为MessageConsumer只能消费Topic中从消费者在MQ服务器注册之后推送到Topic中的消息,至于这之前的消息签收与否MessageConsumer不关心(因为接收不到之前的消息),也就是说使用MessageConsumer消费Topic中的消息时是不会存在重复消费的问题的。
- 对于Topic中的消息而言,若采用TopicSubscriber的模式消费消息时签收机制可以避免重复消费消息的作用就凸显出来了,此时消息的签收将会作为某个订阅者(以Connection的ClientID作为标识)已消费过Topic中的某个消息的标志,也就是说消费者每次上线后都只会消费订阅的Topic中未被签收的消息,已签收的消息则不会被重复消费。
签收机制有四种:
- Session.AUTO_ACKNOWLEDGE:值为1,自动签收,消费一条签收一条
- Session.CLIENT_ACKNOWLEDGE:值为2,手动签收,需显示调用Message.acknowledge()方法完成签收
- Session.DUPS_OK_ACKNOWLEDGE:值为3, "消息可重复"确认,意思是此模式下,可能会出现重复消息,并不是一条消息需要发送多次ACK才行。它是一种潜在的"AUTO_ACK"确认机制,为批量确认而生,而且具有“延迟”确认的特点。对于开发者而言,这种模式下的代码结构和AUTO_ACKNOWLEDGE一样,不需要像CLIENT_ACKNOWLEDGE那样调用acknowledge()方法来确认消息。
- Session.SESSION_TRANSACTED:值为4,以事务的方式签收
事务对消息签收的影响:
消息签收是事务控制的一部分
- 事务的方式,对消息的签收有影响,只要事务提交就会将所有消息的签收状态置为已签收,无论之前的签收状态是什么;
- 只要事务不提交则消息的签收状态就不起作用(表现上就是队列中已签收的消息不会被移出待消费队列等),会产生重复消费得问题。
- 非事务的方式,不会对消息的签收有任何影响