Spring AMQP - Publisher Confirms解决MQ丢消息

Jie 2017/03/23

一、分析

依据RabbitMQ和Spring AMQP参考文档,事务(Transactional)或发布确认(Publisher Confirms / aka Publisher Acknowledgements)机制可保证消息被正确投递,即从理论上来说MQ不会丢消息。
注意这两种机制不能共存。事务机制是重量级的,同步的,会带来大量开销;发布确认机制则是轻量级的,异步的。
对于发布确认机制,(1) 需置CachingConnectionFactory的publisherConfirms属性为true;(2) 生产者需调用setConfirmCallback(ConfirmCallback callback),Confirms就会回调给生产者;(3) 消费者需考虑消息去重处理。
这里需要注意的是,一个RabbitTemplate只能支持一个ConfirmCallback。

二、具体实施项

生产者需修改XML配置和代码,使用RabbitTemplate的带CorrelationData 参数版本的convertAndSend()或send()方法发送消息;消费者则需要增加消息去重处理。

<!-- 配置RabbitMQ连接工厂:开启发布确认机制 -->
<rabbit:connection-factory id="connectionFactoryConfirm" ... publisher-confirms="true" />
<rabbit:admin connection-factory="connectionFactoryConfirm" />
<!-- 声明队列、Exchange以及binding -->
<rabbit:queue name="Queue名" durable="true" auto-delete="false" exclusive="false" />
<!-- Direct Exchange -->
<rabbit:direct-exchange name="Exchange名">
<rabbit:bindings>
<rabbit:binding queue="Queue名" />
</rabbit:bindings>
</rabbit:direct-exchange>

<!-- 生产者配置RabbitTemplate。如果通过代码创建就不需要 -->
<rabbit:template id="rabbitTemplateConfirm" connection-factory="connectionFactoryConfirm" />

<!-- 消费者配置 -->
<!-- 声明bean -->
<bean id="" class=" " />
<!-- 声明监听器容器和监听器 -->
<rabbit:listener-container connection-factory="connectionFactoryConfirm">
<rabbit:listener ref="" method="" queue-names="Queue名" />
</rabbit:listener-container>

// 生产者代码:
// RabbitTemplate对象可通过模板bean注入:
@Autowired
public Class(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}
// 或者创建默认策略和设置的RabbitTemplate对象:
@Autowired
@Qualifier("connectionFactoryConfirm")
private ConnectionFactory connectionFactoryConfirm;
// ...
{
rabbitTemplate = new RabbitTemplate(connectionFactoryConfirm);
}

// 初始化,安装ConfirmCallback
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
if (ack) {
// 处理ack
} else {
// 处理nack, 此时cause包含nack的原因。
// 如当发送消息给一个不存在的Exchange。这种情况Broker会关闭Channel;
// 当Broker关闭或发生网络故障时,需要重新发送消息。
// 暂时先日志记录,包括correlationData, cause等。
}
}
});
// 注意生产者在发送消息时还需提供CorrelationData对象。
rabbitTemplate.convertAndSend("Exchange名", "Routing Key", obj implements Serializable, newCorrelationData("自定义ID,待讨论确定"));

// 消费者代码:
// 注意开启发布确认机制后,消息可能会被重复传递,消费者应做去重处理。



————————————————
参考文献:
[1] Spring AMQP reference - Publisher Confirms. (http://docs.spring.io/spring-amqp/docs/1.5.6.RELEASE/reference/html/_reference.html#template-confirms)
[2] RabbitMQ - Confirms(http://www.rabbitmq.com/confirms.html)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值