spring rabbitmq 消息确认机制和事务支持
来源:互联网 发布:怎样做网络宣传 编辑:程序博客网 时间:2024/06/05 03:04
确认并且保证消息被送达,提供了两种方式:发布确认和事务。(两者不可同时使用)在channel为事务时,不可引入确认模式;同样channel为确认模式下,不可使用事务。
发布确认:
Confirms给客户端一种轻量级的方式,能够跟踪哪些消息被broker处理,哪些可能因为broker宕掉或者网络失败的情况而重新发布。
确认消息是否到达broker服务器,也就是只确认是否正确到达exchange中即可,只要正确的到达exchange中,broker即可确认该消息返回给客户端ack。
有两种方式:消息的确认和消息发送失败的回调。
消息确认:
在配置connectionFactory 中启用消息确认:
<bean id="connectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory"> <property name="host" value="${rabbitmq.host}" /> <property name="port" value="${rabbitmq.port}" /> <property name="username" value="${rabbitmq.username}" /> <property name="password" value="${rabbitmq.password}" /> <property name="virtualHost" value="${rabbitmq.virtualHost}" /> <!-- 缓存模式 CONNECTION CHANNEL,默认的缓存模式是CHANNEL。 当缓存模式是 CONNECTION时, 队列的自动声明等等 (参考 the section called “Automatic Declaration of Exchanges, Queues and Bindings”) 将不再支持。 在框架(如. RabbitTemplate) 中使用的通道将会可靠地返回到缓存中.如果在框架外创建了通道 (如.直接访问connection(s)并调用 createChannel() ), 你必须可靠地返回它们(通过关闭),也许需要在 finally 块中以防止耗尽通道. --> <property name="cacheMode" value="CHANNEL"/> <!-- 默认通道缓存25,多线程环境中,较小的缓存意味着通道的创建和关闭将以很高的速率运行.加大默认缓存大小可避免这种开销 如果达到了限制,调用线程将会阻塞,直到某个通道可用或者超时, 在后者的情况中,将抛出 AmqpTimeoutException异常.--> <property name="channelCacheSize" value="10"/> <!-- channelCheckoutTimeout属性. 当此属性的值大于0时, channelCacheSize会变成连接上创建通道数目的限制. --> <property name="channelCheckoutTimeout" value="200"/> <!-- 发布确认必须配置在CachingConnectionFactory上 --> <property name="publisherConfirms" value="true"/> </bean>模板配置消息确认回调方法:
<bean id="confirmCallback" class="com.convict.rabbitmq.spring.sync.callback.MsgSendConfirmCallBack"/> <!-- 同步访问rabbitmq--> <bean id="rabbitTemplate" class="org.springframework.amqp.rabbit.core.RabbitTemplate"> <constructor-arg name="connectionFactory" ref="connectionFactory"/> <property name="exchange" value="${rabbitmq.exchangeName}"/> <!-- 也可以在发送的时候手动设置routing key --> <property name="routingKey" value="${rabbitmq.msg.routing}"/> <!--消息确认回调 --> <property name="confirmCallback" ref="confirmCallback"/> </bean>
MsgSendConfirmCallBack 代码如下:
public class MsgSendConfirmCallBack implements RabbitTemplate.ConfirmCallback { @Override public void confirm(CorrelationData correlationData, boolean ack, String cause) { if (ack) { System.out.println("消息确认成功"); } else { //处理丢失的消息 System.out.println("消息确认失败,"+cause); } } }
CachingConnectionFactory配置中启用回调
<property name="publisherReturns" value="true"/>
定义回调方法,并在消息模板中指定
<bean id="sendReturnCallback" class="com.convict.rabbitmq.spring.sync.callback.MsgSendReturnCallback"/><bean id="rabbitTemplate" class="org.springframework.amqp.rabbit.core.RabbitTemplate"> <constructor-arg name="connectionFactory" ref="connectionFactory"/> <property name="exchange" value="${rabbitmq.exchangeName}"/> <!-- 也可以在发送的时候手动设置routing key --> <property name="routingKey" value="${rabbitmq.msg.routing}"/> <property name="returnCallback" ref="sendReturnCallback"/> </bean>MsgSendReturnCallback 方法如下:
public class MsgSendReturnCallback implements RabbitTemplate.ReturnCallback {@Overridepublic void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {String msgJson = new String(message.getBody());System.out.println("Returned Message:"+msgJson);}}
事务
Spring AMQP做的不仅仅是回滚事务,而且可以手动拒绝消息,如当监听容器发生异常时是否重新入队。
持久化的消息是应该在broker重启前都有效。如果在消息有机会写入到磁盘之前broker宕掉,消息仍然会丢失。在某些情况下,这是不够的,发布者需要知道消息是否处理正确。简单的解决方案是使用事务,即提交每条消息。
使用事务有两个问题:
一、会阻塞,发布者必须等待broker处理每个消息。如果发布者知道在broker死掉之前哪些消息没有被处理就足够了。
二、事务是重量级的,每次提交都需要fsync(),需要耗费大量的时间。
confirm模式下,broker将会确认消息并处理。这种模式下是异步的,生产者可以流水式的发布而不用等待broker,broker可以批量的往磁盘写入。
场景:业务处理伴随消息的发送,业务处理失败(事物回滚)后要求消息不发送。rabbitmq 使用调用者的外部事物。
示例:使用spring事物,来处理业务并发送消息,并且把消息记录到数据库中防止消息的丢失。
代码说明:
1、rabbitTemplate 使用外部事物配置
<!-- 同步访问rabbitmq--> <bean id="rabbitTemplate" class="org.springframework.amqp.rabbit.core.RabbitTemplate"> <constructor-arg name="connectionFactory" ref="connectionFactory"/> <property name="exchange" value="${rabbitmq.exchangeName}"/> <!-- 也可以在发送的时候手动设置routing key --> <property name="routingKey" value="${rabbitmq.msg.routing}"/> <!-- 使用外部事物 --> <property name="channelTransacted" value="true"/> </bean>2、创建消息表 CREATE TABLE tb_msg(id BIGINT,tag INT,txt TEXT); 使用 spring-mybatis 搭建表的操作,配置事物。
3、模拟 MsgService 中业务处理方法如下(事物切面在service层):
public void addMsg(Msg msg) throws Exception { //模拟业务操作 Thread.sleep(1000); //消息保存到数据库,和业务操作为同一个事物 msgDao.insert(msg); //发送消息 rabbitTemplate.convertAndSend(msg.getTxt()); if (msg.getId() == null || msg.getId() % 2 == 0) {//事物,偶数的回滚 throw new Exception(); } }
当事物回滚,消息也不会发送。
注意:一个具有事务的channel不能放入到确认模式,同样确认模式下的channel不能用事务。
完整code:http://download.csdn.net/detail/convict_eva/9625428
参考:http://my.oschina.net/lzhaoqiang/blog/670749
0 0
- spring rabbitmq 消息确认机制和事务支持
- RabbitMQ 消息持久化、事务、Publisher的消息确认机制
- RabbitMQ消息确认机制
- rabbitmq 消息确认机制
- RabbitMQ集群和消息传递确认机制
- RabbitMQ之消息确认机制(事务+Confirm)
- RabbitMQ(三)消息确认机制(事务+Confirm)
- RabbitMQ之消息确认机制(事务+Confirm)
- RabbitMQ 消息轮询和消息确认机制
- RabbitMQ 消息轮询和消息确认机制
- rabbitmq消息重新入队和消息确认
- rabbitmq的发布确认和事务
- RabbitMQ消息队列(九):Publisher的消息确认机制
- RabbitMQ消息队列(九):Publisher的消息确认机制
- RabbitMQ消息队列(九):Publisher的消息确认机制
- RabbitMQ消息队列(九):Publisher的消息确认机制
- RabbitMQ消息队列(九):Publisher的消息确认机制
- RabbitMQ消息队列(九):Publisher的消息确认机制
- java设计模式进阶_intercepting-filter
- Spring连接多个数据源
- 搭建一个android项目的准备工作
- IntelliJ IDEA+JetBrains WebStorm )+JetBrains PhpStorm +JetBrains(2016.2)版本的破解方法总结
- linux 平台下 postgres 使用 (安装 启动 关闭 数据备份 还原)
- spring rabbitmq 消息确认机制和事务支持
- MFC CString 和int相互转化
- vue.js学习笔记(相关概念)
- IOS 拍照上传图片, 出错: 413 Request Entity Too Large
- 关于跨域,以及跨域的几种方式
- TSO、UFO、GSO、LRO、GRO和RSS介绍(ethtool命令)
- 电子商务考试
- DB9 在 RS232 通讯上的应用接法详解
- faster rcnn源码解读总结