继续上篇文章解决RabbitMQ消息丢失问题和保证消息可靠性(一) 未完成部分,我们聊聊MQ Server端的高可用和消费端如何保证消息不丢的问题?

回归上篇的内容,我们知道消息从生产端到服务端,为了保证消息不丢,我们必须做哪些事情?

  • 发送端采用Confirm模式,注意Server端没成功通知发送端,需要重发操作需要额外处理
  • 消息的持久化处理

上面两个操作保证消息到服务端不丢,但是非高可用状态,如果节点挂掉,服务暂时不可用,需要重启后,消息恢复,消息不会丢失,因为有磁盘存储。

本文先从消费端讲起:

RabbitMQ Server到消费者消息如何不丢?

上面一篇文章也提到了,消费者获取到消息之后,没有来得及处理完毕,自己直接宕机了,因为消息者默认采用自动ack,此时RabbitMQ的自动ack机制会通知MQ Server这条消息已经处理好了,此时消息就丢了,并不是预期的。

那么我们采用手动ack机制来解决这个问题,消费端处理完逻辑之后再通知MQ Server,这样消费者没处理完消息不会发送ack,如果在消费者拿到消息,没来得及处理的情况下自己挂了,此时MQ集群会自动感知到,它就会自觉的重发消息给其他的消费者服务实例。

根据上面的思路你需要完成下面的两步操作:

第一:消费者监听设置手动ack

  1. this.channel = channelManager.getListenerChannel(namespace);
  2. this.queue = queue;
  3. this.channel.basicConsume(queue, false, consumerTag, this);
  4. this.disconnectedCallback.setChannel(channel);

核心代码: this.channel.basicConsume(queue, false, consumerTag, this); 第二个参数设置 false 代表不自动ack

第二:业务执行完成后手动ack

  1. public static void ack(MessageContext context) {
  2. long deliveryTag = context.getEnvelope().getDeliveryTag();
  3. try {
  4. context.getChannel().basicAck(deliveryTag, false);
  5. } catch (IOException e) {
  6. throw new MqAckException("消息ack出错:连接异常或远端关闭", context, e);
  7. }
  8. }

核心代码: context.getChannel().basicAck(deliveryTag, false);

这里封装来,需要业务在执行完自己的业务代码后,调用对象channel 的ack方法通知MQServer,说我这边执行完了,你可以删除了。

注意这里有个问题: 如果忘记调用这个 context.getChannel().basicAck(deliveryTag, false);

或者因为代码异常,这个代码没被执行,会怎么样?后面找时间再写一篇文章讲这个问题。

RabbitMQ Server中存储的消息高可用

当我们解决了,生产端和消费端的问题后,基本保证消息的不丢问题,但是还有一个是消息的高可用问题,单节点问题,普通节点的问题都会影响消息的临时不可用,这个时候要用上我们的HA 镜像集群模式来保证。

上一篇文章 解决RabbitMQ消息丢失问题和保证消息可靠性(一) 已经提到过,服务端消息部署的三种模式的区别,今天就专门讲镜像模式的介绍。

镜像模式至少采用3节点,2个磁盘节点和1个内存节点来保证,架构图:

设置镜像也有一些策略:

  • 同步至所有的,一般不这么做,性能会受到极大影响
  • 同步最多N个机器
  • 只同步至符合指定名称的nodes

命令处理HA策略模版:rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]

  1. 为每个以“rock.wechat”开头的队列设置所有节点的镜像,并且设置为自动同步模式
  1. rabbitmqctl set_policy ha-all "^rock.wechat" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
  2. rabbitmqctl set_policy -p rock ha-all "^rock.wechat" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
  1. 为每个以“rock.wechat.”开头的队列设置两个节点的镜像,并且设置为自动同步模式
  1. rabbitmqctl set_policy -p rock ha-exacly "^rock.wechat" \
  2. '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'
  1. 为每个以“node.”开头的队列分配指定的节点做镜像
  1. rabbitmqctl set_policy ha-nodes "^nodes\." \
  2. '{"ha-mode":"nodes","ha-params":["rabbit@nodeA", "rabbit@nodeB"]}'

但是:HA 镜像队列有一个很大的缺点就是: 系统的吞吐量会有所下降

所以采用镜像模式,要根据具体的业务规则定制话处理,没那么重要的业务,消息丢了也没关系的场景,又要求必须高的性能的时候,镜像也可以不用设置。

总结

两篇文章的讲解,分析了消息中间件高可用问题的大概的思路,没有具体的代码详细,如有疑问可以下方留言评论,我会及时回复解答,后面我会逐步完善相关细节,欢迎多多关注。

后面计划更新文章如下:

  • 什么情况会导致重复消费并怎么解决?
  • 什么样的真实业务场景需要保障顺序性和如何保证消息的顺序性?
  • 如何通过消息队列优雅的解决微服务间接口失败的重试?

推荐阅读

解决RabbitMQ消息丢失问题和保证消息可靠性(一)

IntelliJ IDEA提升效率开发插件必备

END

如有收获,请帮忙转发,后续会有更好文章贡献,您的鼓励是作者最大的动力!

欢迎关注我的公众号:架构师的修炼,获得独家整理的学习资源和日常干货推送。

RabbitMQ消息丢失问题和保证消息可靠性-消费端不丢消息和HA(二)的更多相关文章

  1. 解决RabbitMQ消息丢失问题和保证消息可靠性(一)

    原文链接(作者一个人):https://juejin.im/post/5d468591f265da03b810427e 工作中经常用到消息中间件来解决系统间的解耦问题或者高并发消峰问题,但是消息的可靠 ...

  2. RabbitMQ-消费者"未处理完的消息"丢失

    一个关于客户端(消费者)开启自动应答,重启后"未处理消息丢失"的小坑.(主要是对RabbitMQ理解不够) 首先,申明一下: 本文所谓的 "丢失消息" 不是指服 ...

  3. 如何保证mq不丢消息

    1.消息的发送流程 一条消息从生产到被消费,将会经历3个阶段 生产阶段,Producer 新建消息,然后通过网络将消息投递给MQ Broker 存储阶段,消息将会存储在Broker端磁盘中 消费阶段, ...

  4. MQ的消息丢失/重复/积压的问题解决

    在我们实际的开发过程中,我们肯定会用到MQ中间件,常见的MQ中间件有kafka,RabbitMQ,RocketMQ.在使用的过程中,我们必须要考虑这样一个问题,在使用MQ的时候,我们怎么确保消息100 ...

  5. kafka实现无消息丢失与精确一次语义(exactly once)处理

    在很多的流处理框架的介绍中,都会说kafka是一个可靠的数据源,并且推荐使用Kafka当作数据源来进行使用.这是因为与其他消息引擎系统相比,kafka提供了可靠的数据保存及备份机制.并且通过消费者位移 ...

  6. 消费端如何保证消息队列MQ的有序消费

    消息无序产生的原因 消息队列,既然是队列就能保证消息在进入队列,以及出队列的时候保证消息的有序性,显然这是在消息的生产端(Producer),但是往往在生产环境中有多个消息的消费端(Consumer) ...

  7. activemq热备与消息丢失

    1. 解压 tar -zxvf apache-activemq-5.12.0-bin.tar.gz2. 改名 mv apache-activemq-5.12.0 activemq3. cd activ ...

  8. kafka什么时候会丢消息(转)

    因为在具体开发中某些环节考虑使用kafka却担心有消息丢失的风险,本周结合项目对kafka的消息可靠性做了一下调研和总结: 首先明确一下丢消息的定义.kafka集群中的部分或全部broker挂了,导致 ...

  9. 【Microsoft Azure学习之旅】测试消息队列(Service Bus Queue)是否会丢消息

    组里最近遇到一个问题,微软的Azure Service Bus Queue是否可靠?是否会出现丢失消息的情况? 具体缘由如下, 由于开发的产品是SaaS产品,为防止消息丢失,跨Module消息传递使用 ...

随机推荐

  1. (读论文)推荐系统之ctr预估-DeepFM模型解析

    今天第二篇(最近更新的都是Deep模型,传统的线性模型会后面找个时间更新的哈).本篇介绍华为的DeepFM模型 (2017年),此模型在 Wide&Deep 的基础上进行改进,成功解决了一些问 ...

  2. 第2个C# Winform实例,寻找三角形的位置

    这里,在第一个例子的基础上,稍微做修改,达到最终定位三角形位置的目的. 先在网络上找一张包含有三角形的图片,我们这里使用一张有三个三角形和一些标记的图片来处理. 原图: 先贴结果图片:左侧,中间,右侧 ...

  3. shiro 和 spring boot 的集成

    1 添加依赖 使用 shiro-spring-boot-web-starter 在 spring boot 中集成 shiro 只需要再添加一个依赖 <dependency> <gr ...

  4. T-SQL 小全

    --====================================================== ----数据库概念:创建.删除.使用数据库 ----================= ...

  5. win10下nodejs的安装及配置

    这里主要引用两篇文章,写的非常详细,也能解决你可能出现的问题 nodejs安装及配置 如何删除之前nodejs设置的 npm config set prefix .....

  6. 【iOS】Receiver type 'XXX' for instance message is a forward declaration

    今天遇到这个错误.刚开始字体太大,没显示全,后来调小字体之后看到了完整提示信息: 之后就忽然想起没引入相关的类,添加 #import "RDVTabBarItem.h" 就行了.

  7. ansible-yum

    #yum 需要在vim /etc/ansible/hosts里面给执行的主机配置 远程调用python的路径不知道为什么默认值认识python2.6.6 vim /etc/ansible/hosts ...

  8. Another option to bootup evidence files

    When it comes to booting up evidence files acquired from target disk, you got two options. One is VF ...

  9. 破解EFCore扩展Dll --- Z.EntityFramework.Extensions.EFCore

    安装 Z.EntityFramework.Extensions.EFCore Install-Package Z.EntityFramework.Extensions.EFCore -Version ...

  10. dubbo是如何控制并发数和限流的?

    ExecuteLimitFilter ExecuteLimitFilter ,在服务提供者,通过 的 "executes" 统一配置项开启: 表示每服务的每方法最大可并行执行请求数 ...