RabbitMQ学习四(消息可靠性投递的两种方式)
一.消息可靠性
为了防止消息在投递的过程中进行丢失,所以存在一个消息可靠性。
1.消息投递路径
producer->rabbitmq broker->exchange->queue->consumer
2.RabbitMQ提供的两种方式
- confirm确认模式
消息从producer->exchange会返回一个confirmCallback;他可以记录消息是否发送成功
- return退回模式
消息从exchange -> queue会返回一个returnCallback;他可以记录消息是否发送成功
可以利用这两个标识控制消息的可靠性。如果接收失败了,可以再次发送。
3.confirm确认模式
3.1.添写配置文件
rabbitmq.host=127.0.0.1
rabbitmq.port=5672
rabbitmq.username=guest
rabbitmq.password=guest
rabbitmq.virtual-host=/
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:rabbit="http://www.springframework.org/schema/rabbit" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd"> <!--加载配置文件--> <context:property-placeholder location="classpath:rabbitmq.properties"/> <!-- 定义rabbitmq connectionFactory --> <rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}" port="${rabbitmq.port}" username="${rabbitmq.username}" password="${rabbitmq.password}" virtual-host="${rabbitmq.virtual-host}" publisher-confirms="true" publisher-returns="true" /> <!--定义管理交换机、队列--> <rabbit:admin connection-factory="connectionFactory"/> <!--定义rabbitTemplate对象操作可以在代码中方便发送消息--> <rabbit:template id="rabbitTemplate" connection-factory="connectionFactory"/> <!--消息可靠性投递(生产端)--> <rabbit:queue id="test_queue_confirm" name="test_queue_confirm"></rabbit:queue> <rabbit:direct-exchange name="test_exchange_confirm"> <rabbit:bindings> <rabbit:binding queue="test_queue_confirm" key="confirm"></rabbit:binding> </rabbit:bindings> </rabbit:direct-exchange> </beans>
3.2.写测试类测试
package com.itheima.test; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.connection.CorrelationData; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:spring-rabbitmq-producer.xml") public class ProducerTest { @Autowired private RabbitTemplate rabbitTemplate; /* * 确认模式 * 步骤: * 1.确认模式开启:在xml文件中connection-factory中开启publisher-confirms="true" * 2.在rabbitTemplate定义ConfirmCallBack回调函数 * */ @Test public void testConfirm(){ //2.定义回调 rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() { /* * confirm参数: * 1.correlationData:相关的配置信息 * 2.b:交换机是否成功收到消息;true代表成功,false代表失败 * 3.s:失败的原因 * */ @Override public void confirm(CorrelationData correlationData, boolean b, String s) { System.out.println("confirm方法被执行了"); if (b){ //接收成功 System.out.println("接收成功"); }else{ //接收失败 System.out.println("接收失败"+s); //做一些处理 } } }); //3.发送消息 rabbitTemplate.convertAndSend("test_exchange_confirm","confirm","message confirm"); } }
3.return退回模式
配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:rabbit="http://www.springframework.org/schema/rabbit" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd"> <!--加载配置文件--> <context:property-placeholder location="classpath:rabbitmq.properties"/> <!-- 定义rabbitmq connectionFactory --> <rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}" port="${rabbitmq.port}" username="${rabbitmq.username}" password="${rabbitmq.password}" virtual-host="${rabbitmq.virtual-host}" publisher-confirms="true" publisher-returns="true" /> <!--定义管理交换机、队列--> <rabbit:admin connection-factory="connectionFactory"/> <!--定义rabbitTemplate对象操作可以在代码中方便发送消息--> <rabbit:template id="rabbitTemplate" connection-factory="connectionFactory"/> <!--消息可靠性投递(生产端)--> <rabbit:queue id="test_queue_confirm" name="test_queue_confirm"></rabbit:queue> <rabbit:direct-exchange name="test_exchange_confirm"> <rabbit:bindings> <rabbit:binding queue="test_queue_confirm" key="confirm"></rabbit:binding> </rabbit:bindings> </rabbit:direct-exchange> </beans>
测试文件
package com.itheima.test; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.connection.CorrelationData; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:spring-rabbitmq-producer.xml") public class ProducerTest { @Autowired private RabbitTemplate rabbitTemplate; /* * 回退模式:当消息发送给Exchange后,Exchange路由到Queue失败时,才会执行ReturnCallBack * 步骤: * 1.开启回退模式:publisher-returns="true" * 2.设置ReturnCallBack * 3.设置Exchange处理消息的模式: * 1.如果消息没有路由到Queue,则丢弃消息(默认) * 2.如果消息没有路由到Queue,则ReturnCallBack将会执行 * */ @Test public void testReturn(){ //设置交换机处理消息的模式 rabbitTemplate.setMandatory(true); rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() { /** * * @param message 消息对象 * @param i 错误码 * @param s 错误信息 * @param s1 交换机 * @param s2 路由键 */ @Override public void returnedMessage(Message message, int i, String s, String s1, String s2) { System.out.println(message); System.out.println(i); System.out.println(s); System.out.println(s1); System.out.println(s2); System.out.println("Return执行了"); } }); //3.发送消息 rabbitTemplate.convertAndSend("test_exchange_confirm","confirm","message confirm"); } }

浙公网安备 33010602011771号