生产者端
目录结构
导入依赖
修改yml
业务逻辑
测试结果
生产者端
目录结构
导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
修改yml
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
publisher-confirm-type: correlated # 开启确认回调
publisher-returns: true # 开启退回回调
在publisher-confirm-type中有三个确认消息接受类型:none、correlated、simple。
publisher-confirm-type: none 表示禁用发布确认模式。是默认值。使用此模式之后,不管消息有没有发送到Broker(RabbitMQ)都不会触发ConfirmCallback回调。
publisher-confirm-type: correlated 表示消息成功到达Broker后触发ConfirmCalllBack回调。
publisher-confirm-type: simple 表示如果消息成功到达Broker后一样会触发ConfirmCalllBack回调,发布消息成功后使用rabbitTemplate调用waitForConfirms()或waitForConfirmsOrDie()方法等待Broker节点返回发送结果,根据返回结果来判定下一步的逻辑。如果waitForConfirmsOrDie()方法如果返回false则会关闭channel信道,则接下来无法发送消息到Broker。
业务逻辑
@SpringBootTest
@RunWith(SpringRunner.class)
class RabbitmqProducerApplicationTests {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
void testProducer() {
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
//三个参数分别为:相关配置消息、交换机是否收到消息、未收到消息的原因
@Override
public void confirm(CorrelationData correlationData, boolean b, String s) {
if(b) System.out.println("交换机成功接受到了消息");
else System.out.println("消息失败原因" + s);
}
});
rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
//五个参数分别为:消息对象、失败状态码、失败信息、交换机名称、路由键
@Override
public void returnedMessage(Message message, int i, String s, String s1, String s2) {
System.out.println("队列接受不到交换机的消息进行了失败回调");
}
});
rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME,"test.heHe","HelloWorld");
}
}
测试结果
为了测试是否进行了确认回调方法即confirmCallBack()方法,我将上方的交换机名称故意写错
rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME + "1","test.heHe","HelloWorld");
为了测试是否进行了退回回调方法即returnCallBack()方法,我将上方的路由键名称故意写错
rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME,"t.heHe","HelloWorld");
总结
经上方两次测试,可以使用ConfirmCallBack与ReturnCallBack来确认消息的可靠性传递。ConfirmCallBack是确认交换机是否可以成功接收到消息,而ReturnCallBack是确认队列是否可以成功接收到交换机发来的消息。这是作为解决作为消息发送方希望杜绝任何消息丢失或者投递失败场景。 但需要注意的是在yml中必须添加两行配置。