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. CSS3 基础学习

    CSS基础学习 当前进度[P78] 参考资料 视频链接:https://www.bilibili.com/video/BV14J4114768 菜鸟教程:https://www.runoob.com/ ...

  2. Bellman-Ford算法与SPFA算法详解

    PS:如果您只需要Bellman-Ford/SPFA/判负环模板,请到相应的模板部分 上一篇中简单讲解了用于多源最短路的Floyd算法.本篇要介绍的则是用与单源最短路的Bellman-Ford算法和它 ...

  3. vue 将markdown字符串转html、修改主题、生成目录

    前言 将 markdown 字符串转成 html 显示出来,同时把目录也提取出来一起显示.可以使用 marked 来读取 markdown 字符串解析成 html marked官网:https://m ...

  4. Git 06 分支

    参考源 https://www.bilibili.com/video/BV1FE411P7B3?spm_id_from=333.999.0.0 版本 本文章基于 Git 2.35.1.2 概述 分支用 ...

  5. 虚拟DOM解析及其在框架里的应用

    虚拟DOM解析及其在框架里的应用 浏览器是怎样解析HTML并且绘出整个页面的 上图为webkit引擎浏览器的处理流程,如上图大致分为4大步: 第一步,HTML解析器分析html,构建一颗DOM树: 第 ...

  6. MySQL查询关键数据方法

    MySQL查询关键数据方法 操作表的SQL语句补充 1.修改表名 alter table 表名 reame 新表名: 2.新增字段名 alter table 表名 add 字段名 字段类型(数字) 约 ...

  7. 【NOI P模拟赛】(要素过多的标题)(容斥原理)

    题面 0 题目背景 [ 数   据   删   除 ] _{^{[数\,据\,删\,除]}} [数据删除]​ 1 题目描述 在执行任务时,收集到了 n n n 份能源,其中第 i i i 份的能量值是 ...

  8. 【PostgreSQL】PostgreSQL 15移除了Stats Collector

    试用即将发行的PostgreSQL 15的人会发现少了一个后台进程:​ postgres 1710 1 0 04:03 ? 00:00:00 /usr/pgsql-15/bin/postmaster ...

  9. SUSE Linux Enterprise Server 12 使用二进制文件安装docker

    Docker-CE in SUSE 虽然使用zypper添加源也能安装,不过我在SLES 12sp5 上安装时发现好多命令还需要自己手动软连接,干脆网上找了找文档,再自己小改下,用二进制部署,也是可以 ...

  10. Android平台摄像头/屏幕/外部数据采集及RTMP推送接口设计描述

    好多开发者提到,为什么大牛直播SDK的Android平台RTMP推送接口怎么这么多?不像一些开源或者商业RTMP推送一样,就几个接口,简单明了. 不解释,以Android平台RTMP推送模块常用接口, ...