Publisher Confirms发布确认是用于实现可靠发布的RabbitMQ扩展。

我们将使用发布确认来确保已发布的消息已安全到达代理。我们将介绍几种使用publisher确认的策略,并解释其优缺点

首先检查application.yml文件

spring:
rabbitmq:
host: 127.0.0.1
# 之前博客未加端口,此处新增
port: 5672
username: guest
password: guest
virtualHost: /
1. 单独发布消息
  • 新增配置文件PublishConfirmConfig.java
@Configuration
public class PublishConfirmConfig { @Bean("myRabbitConnectionFactory")
public ConnectionFactory myRabbitConnectionFactory(RabbitProperties rabbitProperties){
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
cachingConnectionFactory.setHost(rabbitProperties.getHost());
cachingConnectionFactory.setPort(rabbitProperties.getPort());
cachingConnectionFactory.setUsername(rabbitProperties.getUsername());
cachingConnectionFactory.setPassword(rabbitProperties.getPassword());
cachingConnectionFactory.setVirtualHost("/");
return cachingConnectionFactory;
} @Bean
public RabbitTemplate simpleRabbitTemplate(ConnectionFactory myRabbitConnectionFactory) {
CachingConnectionFactory connectionFactory = (CachingConnectionFactory) myRabbitConnectionFactory;
connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.SIMPLE);
connectionFactory.setPublisherReturns(true);
final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(producerJackson2MessageConverter());
return rabbitTemplate;
} @Bean
public Jackson2JsonMessageConverter producerJackson2MessageConverter(){
return new Jackson2JsonMessageConverter();
}
}
  • 新增发送文件PublishConfirmSender.java
@Component
public class PublishConfirmSender { private RabbitTemplate simpleRabbitTemplate; public PublishConfirmSender(RabbitTemplate simpleRabbitTemplate) {
this.simpleRabbitTemplate = simpleRabbitTemplate;
} public void oneSender() {
boolean sendFlag = simpleRabbitTemplate.invoke(operations -> {
simpleRabbitTemplate.convertAndSend("direct", "orange", "orange msg");
return simpleRabbitTemplate.waitForConfirms(5000);
});
if (sendFlag) {
System.out.println("消息已成功发送");
}
}
}
  • 测试发送
@SpringBootTest
public class RabbitTest {
@Autowired
private PublishConfirmSender publishConfirmSender; @Test
public void testOneSender() {
publishConfirmSender.oneSender();
}
}

2. 批量消息发布确认
@Component
public class PublishConfirmSender { ............ public void batchSender() {
boolean sendFlag = simpleRabbitTemplate.invoke(operations -> {
for (int i = 0; i < 50; i++) {
simpleRabbitTemplate.convertAndSend("direct", "orange", "orange " + i + "msg");
if (i % 10 == 0) {
if (simpleRabbitTemplate.waitForConfirms(5000)) {
System.out.println(i / 10 + "批次消息已全部成功发送");
}
}
}
return simpleRabbitTemplate.waitForConfirms(5000);
});
if (sendFlag) {
System.out.println("消息已全部成功发送");
}
}
}

3. 发布服务器异步确认
@Component
public class PublishConfirmSender {
......
@Bean
@Primary
public RabbitTemplate asyncRabbitTemplate(ConnectionFactory myRabbitConnectionFactory) {
CachingConnectionFactory connectionFactory = (CachingConnectionFactory) myRabbitConnectionFactory;
connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED);
connectionFactory.setPublisherReturns(true);
final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(producerJackson2MessageConverter());
rabbitTemplate.setMandatory(true);
return rabbitTemplate;
}
}
@Component
public class PublishConfirmSender {
public void asyncSender() {
asyncRabbitTemplate.invoke(operations -> {
for (int i = 0; i < 50; i++) {
String body = "orange " + i + "msg";
simpleRabbitTemplate.convertAndSend("direct", "orange", body);
}
return null;
}, (deliveryTag, multiple) -> {
System.out.format("消息已确认. Sequence number: %d, multiple: %b%n", deliveryTag, multiple);
}, (deliveryTag, multiple) -> {
System.err.format("消息未确认. Sequence number: %d, multiple: %b%n",deliveryTag, multiple);
});
}
}

4. 总结

在某些应用程序中,确保将发布的消息发送给代理是至关重要的。Publisher确认有助于满足此要求的RabbitMQ功能。Publisher确认本质上是异步的,但也可以同步处理它们。没有明确的方法来实现publisher确认,这通常归结为应用程序和整个系统中的约束。典型技术包括

  • 单独发布消息,同步等待确认:简单,但吞吐量非常有限。
  • 批量发布消息,同步等待批处理的确认:简单、合理的吞吐量,但很难判断何时出错。
  • 异步处理:最佳性能和资源利用率,在发生错误时进行良好控制,但需要正确处理。

欢迎关注公众号算法小生沈健的技术博客

9. RabbitMQ系列之消息发布确认的更多相关文章

  1. 【python】-- RabbitMQ Publish\Subscribe(消息发布\订阅)

    RabbitMQ RabbitMQ Publish\Subscribe(消息发布\订阅) 1对1的消息发送和接收,即消息只能发送到指定的queue里,但这样使用有些局限性,有些时候你想让你的消息被所有 ...

  2. rabbitmq系列三 之发布/订阅

    1.发布/订阅 在上篇教程中,我们搭建了一个工作队列,每个任务只分发给一个工作者(worker).在本篇教程中,我们要做的跟之前完全不一样 —— 分发一个消息给多个消费者(consumers).这种模 ...

  3. RabbitMQ系列(四)--消息如何保证可靠性传输以及幂等性

    一.消息如何保证可靠性传输 1.1.可能出现消息丢失的情况 1.Producer在把Message发送Broker的过程中,因为网络问题等发生丢失,或者Message到了Broker,但是出了问题,没 ...

  4. RabbitMQ消息发布和消费的确认机制

    前言 新公司项目使用的消息队列是RabbitMQ,之前其实没有在实际项目上用过RabbitMQ,所以对它的了解都谈不上入门.趁着周末休息的时间也猛补习了一波,写了两个窗体应用,一个消息发布端和消息消费 ...

  5. RabbitMQ系列(四)RabbitMQ事务和Confirm发送方消息确认——深入解读

    RabbitMQ事务和Confirm发送方消息确认--深入解读 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建 深入了解RabbitMQ工作原理及简单使用 RabbitMQ交换器 ...

  6. RabbitMQ消息队列(六)-消息任务分发与消息ACK确认机制(.Net Core版)

    在前面一章介绍了在.Net Core中如何使用RabbitMQ,至此入门的的部分就完成了,我们内心中一定还有很多疑问:如果多个消费者消费同一个队列怎么办?如果这几个消费者分任务的权重不同怎么办?怎么把 ...

  7. 【rabbitmq】rabbitmq概念解析--消息确认--示例程序

    概述 本示例程序全部来自rabbitmq官方示例程序,rabbitmq-demo: 官方共有6个demo,针对不同的语言(如 C#,Java,Spring-AMQP等),都有不同的示例程序: 本示例程 ...

  8. RabbitMQ系列教程之三:发布/订阅(Publish/Subscribe)(转载)

    RabbitMQ系列教程之三:发布/订阅(Publish/Subscribe) (本教程是使用Net客户端,也就是针对微软技术平台的) 在前一个教程中,我们创建了一个工作队列.工作队列背后的假设是每个 ...

  9. RabbitMQ (十二) 消息确认机制 - 发布者确认

    消费者确认解决的问题是确认消息是否被消费者"成功消费". 它有个前提条件,那就是生产者发布的消息已经"成功"发送出去了. 因此还需要一个机制来告诉生产者,你发送 ...

随机推荐

  1. SkiaSharp 之 WPF 自绘 粒子花园(案例版)

    此案例包含了简单的碰撞检测,圆形碰撞检测方法,也可以说是五环弹球的升级版,具体可以根据例子参考. 粒子花园 这名字是案例的名字,效果更加具有科技感,很是不错,搞搞做成背景特效也是不错的选择. Wpf ...

  2. Python爬虫:为什么你爬取不到网页数据

    前言: 之前小编写了一篇关于爬虫为什么爬取不到数据文章(文章链接为:Python爬虫经常爬不到数据,或许你可以看一下小编的这篇文章), 但是当时小编也是胡乱编写的,其实里面有很多问题的,现在小编重新发 ...

  3. Apache Dolphinscheduler3.0.0-beta-1 版本发布,新增FlinkSQL、Zeppelin任务类型

    导读:近日,Apache Dolphin Scheduler 迎来了 3.0.0-beta-1 版本的正式发布.新版本主要针对 3.0.0-alpha 进行了代码和文档的修复,并引入了部分的功能,如支 ...

  4. 手把手教你分析MySQL查询性能瓶颈,包教包会

    当一条SQL执行较慢,需要分析性能瓶颈,到底慢在哪? 我们一般会使用Explain查看其执行计划,从执行计划中得知这条SQL有没有使用索引?使用了哪个索引? 但是执行计划显示内容不够详细,如果显示用到 ...

  5. CSS 选择器(一):属性选择器

    属性选择器的介绍 属性选择器顾名思义就是通过标签的属性来查找标签的选择器.让我们来回忆一下标签的属性是什么?HTML5 的所有标签共同拥有的属性叫作全局属性,除此之外还有标签自己拥有的属性,就叫作私有 ...

  6. [WPF]使用DispatcherUnhandledException捕捉未经处理的异常

    使用DispatcherUnhandledException捕捉未经处理的异常 using System.Windows; namespace Test02 { /// <summary> ...

  7. 七分钟学会 HTML 网页制作

    什么是HTML 点击打开视频讲解更加详细 Hyper Text Markup Language(超文本标记语言) 标签控制排版 体积小,方便传输 编写HTLML 推荐使用:VS Code <!D ...

  8. 免杀手法-tcp套字节传递shellcode学习

    免杀手法-tcp套字节传递shellcode学习

  9. KingbaseES 多列分区的方法与性能

    前言 对于多列分区,可以选择单级多列的范围分区,也可以选择范围加子分区的方式.但二者在不同场景下对于性能是有差异的,这里的性能差异主要是分区裁剪引起的差异. 例子 创建两张分区表,采取不同的分区策略: ...

  10. KingbaseES R6 集群通过备库clone在线添加新节点

    案例说明: KingbaseES R6集群可以通过图形化方式在线添加新节点,但是在添加新节点clone环节时,是从主库copy数据到新的节点,这样在生产环境,如果数据量大,将会对主库的网络I/O造成压 ...