本篇和大家分享的是关于rabbit的生产和消费方的一些实用的操作;正如文章标题,主要内容如producer的confirm和consumer的ack,这两者使用的模式都是用来保证数据完整性,防止数据丢失。

  • producer的confirm模式
  • consumer的ack模式

producer的confirm模式

首先,有这样一种业务场景1:a系统在做活动前,需要给用户的手机发送一条活动内容短信希望用户来参加,因为用户量有点大,所以通过往短信mq中插入数据方式,让短信服务来消费mq发短信;

此时插入mq消息的服务为了保证给所有用户发消息,并且要在短时间内插入完成(因此用到了异步插入方式(快速)),我们就需要知道每次插入mq是否成功,如果不成功那我们可以收集失败的信息后补发(因此confirm模式排上了用场);如图设计:

在springboot中可以使用基于amqp封装的工厂类来开启confirm模式,然后通过RabbitTemplate模板来设置回调函数,如下代码:

     ///region producer生产 - confirm模式

     public RabbitTemplate getRabbitTemplate(RabbitTemplate.ConfirmCallback confirmCallback) {
return this.getRabbitTemplate(this.connectionFactory(), confirmCallback);
} public RabbitTemplate getRabbitTemplate(CachingConnectionFactory connectionFactory, RabbitTemplate.ConfirmCallback confirmCallback) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
//product开启confirm模式
connectionFactory.setPublisherConfirms(true);
//设置confirm回调处理
template.setConfirmCallback(confirmCallback);
return template;
}
///endregion

这里通过RabbitTemplate.ConfirmCallback函数编程来传递我们自定义的回调方法,如下收集confirm返回的结果信息:

         RabbitUtil rabbitUtil = new RabbitUtil(this.getFirstNode().getLink());
RabbitTemplate template = rabbitUtil.getRabbitTemplate((a, b, c) -> {
System.out.println("firstNodeTpl - ConfirmCallback的Id:" + a.getId() + ";状态:" + b + ";信息:" + c);
});

最后再通过RabbitTemplate实例的convertAndSend方法发送mq信息,我们能够在日志中看到如下记录的信息:

这里的状态true:表示send成功,false:表示send失败;通常false的时候信息c会有响应的错误提示,这里把网络断开,如下错误提示:

consumer的ack模式

再来,有这样一种场景2:短信服务去消费mq队列信息时,倘若服务调用的运营商发送短信接口异常了(短信运营商接口欠费),我们此时的短信是发送失败的,用户也收不到短信,但是在默认(默认开启ack)前提下mq消息已经被消费了rabbit中没有记录了(kafka例外);想要mq消息在业务逻辑异常时还存在,那么可以使用ack方式;

在springboot中可以使用基于amqp封装的工厂类关闭自动ack模式,改为手动ack方式;只有当业务代码流程走完后,最后通过代码设置ack标识,来通知rabbit消息可以丢弃了;如果设置了手动模式后,又没有提交ack标识,那么mq中的消息一直存在无法释放(每次consumer消费后,rabbit会把noack的消息重复放入队列中):

     ///region consumer监听 - 手动ack
public SimpleRabbitListenerContainerFactory listenerContainerFactory() {
return this.listenerContainerFactory(this.connectionFactory());
} public SimpleRabbitListenerContainerFactory listenerContainerFactory(ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
//代码手动ack
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
//开启消费者数量
factory.setConcurrentConsumers();
//每次接受数据量,默认250
factory.setPrefetchCount();
return factory;
}
///endregion

通过连接工厂设置手动ack方式,然后获取mq消息后,走完正常业务逻辑,最后再手动通知ack释放消息,如下:

     @RabbitListener(containerFactory = "firstNodeListener", queues = {"${shenniu.rabbits.firstNode.queue}"})
private void firstNodeListener(String msg, Channel channel, Message message) {
try {
long deliverTag = message.getMessageProperties().getDeliveryTag();
System.out.println("firstNodeListener - 消费消息 [" + deliverTag + "] - " + msg);
channel.basicAck(deliverTag, true);
} catch (Exception ex) {
}
}

这里ack主要根据mq消息的唯一编号(deliverTag)来通知;如果我们不设置ack确认,那么消息状态会是这样如下rabbit管理后台:

rabbit - producer的confirm和consumer的ack模式的更多相关文章

  1. JAVA消息确认机制之ACK模式

    JMS API中约定了Client端可以使用四种ACK模式,在javax.jms.Session接口中: AUTO_ACKNOWLEDGE = 1    自动确认 CLIENT_ACKNOWLEDGE ...

  2. springboot集成rabbitmq并手动注册容器实现单个queue的ack模式

    原文:https://blog.csdn.net/qq_38439885/article/details/88982373 进入正题,本文会介绍两种实现rabbitmq的ack模式的方法,分别为: 一 ...

  3. kafka producer自定义partitioner和consumer多线程

    为了更好的实现负载均衡和消息的顺序性,Kafka Producer可以通过分发策略发送给指定的Partition.Kafka Java客户端有默认的Partitioner,平均的向目标topic的各个 ...

  4. springcloud服务提供producer and 服务调用consumer

    ---------------------------------producer------------------------------------------- 1.pom文件中,作为客户端的 ...

  5. RabbitMQ的transaction、confirm、ack三个概念的解释

    在使用RabbitMQ的过程中,肯定会遇到这样的几个概念:transaction.confirm.ack.本文介绍一下这几个概念,以及他们之间的关系. RabbitMQ是采用的AMQP协议,AMQP协 ...

  6. 在kafka/config/目录下面有3个配置文件参数说明(producer.properties。consumer.properties。server.properties)

    (1).producer.properties:生产端的配置文件 #指定kafka节点列表,用于获取metadata,不必全部指定 #需要kafka的服务器地址,来获取每一个topic的分片数等元数据 ...

  7. RocketMQ学习笔记(6)----RocketMQ的Client的使用 Producer/Consumer

    1.  添加依赖 pom.xml如下: <dependency> <groupId>org.apache.rocketmq</groupId> <artifa ...

  8. 如何创建Kafka客户端:Avro Producer和Consumer Client

    1.目标 - Kafka客户端 在本文的Kafka客户端中,我们将学习如何使用Kafka API 创建Apache Kafka客户端.有几种方法可以创建Kafka客户端,例如最多一次,至少一次,以及一 ...

  9. RabbitMQ 之消息确认机制(事务+Confirm)

    概述 在 Rabbitmq 中我们可以通过持久化来解决因为服务器异常而导致丢失的问题,除此之外我们还会遇到一个问题:生产者将消息发送出去之后,消息到底有没有正确到达 Rabbit 服务器呢?如果不错得 ...

随机推荐

  1. C#编程之IList、List和ArrayList

    额...今天看了半天Ilist<T>和List<T>的区别,然后惊奇的发现使用IList<T>还是List<T>对我的项目来说没有区别...  在C#中 ...

  2. 黑羽压测 做 API接口功能测试

    做功能测试 黑羽压测 是一款性能测试工具,但是我们也可以使用它,很方便的做 API接口功能测试 . 点击下方链接,观看 讲解视频 https://www.bilibili.com/video/av60 ...

  3. 基于V2EX API的nodejs组件.

    今天又学习到了新的知(zi)识(shi),来给自己做个笔录,也算在这酷热的天气里给自己写了一篇降温的‘膏药’,话就讲这么多了 ,start off...... 首先 ,依赖选择: /**设置为严格模式 ...

  4. thymeleaf常用属性

    转 作者:ITPSC 出处:http://www.cnblogs.com/hjwublog/   th:action 定义后台控制器路径,类似<form>标签的action属性. 例如: ...

  5. Wireshark着色规则

    wireshark抓包蓝色和红色 在默认情况下 蓝色适合红色相反的方向 绿色背景的是HTTP包灰色背景的是TCP包.黑色背景的是TCP错误包或者校验和错误的包 有时候wireshark抓的包还有颜色区 ...

  6. Win常用软件

    本节只适合windows系统 VScode 下载 安装 双击安装 打开目录方式 右键文件夹->使用VSCode打开 命令行打开 code folder [dzlua@win10:~]$ ls a ...

  7. Python基础总结之第九天开始【python之OS模块对目录的操作、以及操作文件】(新手可相互督促)

    年薪20万的梦想...         python对文件.目录能做什么?或者说我们需要python替我们做什么?最经常的操作就是对文件的:打开.关闭.读取.写入.修改.保存等等对目录的操作,无非就是 ...

  8. RFC 2544 性能测试

    什么是RFC 2544?网络设备性能测试的一组指标,包括吞吐率.时延.丢包率.背靠背. * * * 吞吐率(Throughput). 定义:被测设备在不丢包的情况下,所能转发的最大数据流量.通常使用每 ...

  9. 洛谷 P5150 题解

    题面 因为 n=lcm(a,b)n = lcm(a, b)n=lcm(a,b) ,可以得出: a  和 b  的质因数都是 n 的质因数 对于 n  的每个质因数 x ,在 n 中的次数为 y ,那么 ...

  10. Github上fork的项目如何merge原Git项目

    问题场景 小明在Github上fork了一个大佬的项目,并clone到本地开发一段时间,再提交merge request到原Git项目,过了段时间,原作者联系小明,扔给他下面这幅截图并告知合并处理冲突 ...