RabbitMQ学习(五):RabbitMQ持久化

这篇具有很好参考价值的文章主要介绍了RabbitMQ学习(五):RabbitMQ持久化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、持久化概念

在上一章内容中我们已经看到了如何处理任务不丢失的情况,但是如何保障当 RabbitMQ 服务停掉后消 息生产者发送过来的消息不丢失呢?默认情况下 RabbitMQ 退出或由于某种原因崩溃时,它将忽视队列 和消息,除非告知它不要这样做。

确保消息不会丢失需要做两件事:我们需要将队列和消息都标 记为持久化。

二、实现持久化

2.1 队列实现持久化

如果要队列实现持久化,需要在声明队列的时候把 durable 参数设置为持久化 。

boolean durable = true;
channel.queueDeclare(ACK_QUEUE_NAME, durable, false, false, null);

但是需要注意的就是如果之前声明的队列不是持久化的,需要把原先队列先删除,或者重新 创建一个持久化的队列,不然就会出现错误 。

当我们将durable参数位置传递true之后,即使重启 rabbitmq 队列也依然存在。

2.2 消息实现持久化

要想让消息实现持久化需要在消息生产者修改代码,需要像channel的basicPublish方法中props属性中传递MessageProperties.PERSISTENT_TEXT_PLAIN 参数。

将消息标记为持久化并不能保证完全不丢失消息。尽管它告诉 RabbitMQ 将消息保存到磁盘,但是这里依然存在当消息刚准备存储在磁盘,但是还没有存储完,事实上消息还在缓存的一个时间点。在这个时候消息并没有真正写入磁盘,持久性保证并不强。但是对于我们的简单任务队列而言,这已经绰绰有余了。后面的发布确认章节将介绍更强有力的持久化策略。

没有持久化:

channel.basicPublish("", TASK_QUEUE_NAME, null, message.getBytes("UTF-8"));

实现持久化:

channel.basicPublish("", TASK_QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes("UTF-8"));

三、不公平分发

在最开始的时候我们学习到 RabbitMQ 分发消息采用的轮训分发,但是在某种场景下这种策略并不是 很好,比方说有两个消费者在处理任务,其中有个消费者 1 处理任务的速度非常快,而另外一个消费者 2 处理速度却很慢,这个时候我们还是采用轮训分发的话就会到这处理速度快的这个消费者很大一部分时间 处于空闲状态,而处理慢的那个消费者一直在干活,这种分配方式在这种情况下就不合理,但是 RabbitMQ 并不知道这种情况,它依然很公平地进行分发。

为了避免这种情况,我们可以设置参数 channel.basicQos(1);

意思就是如果这个任务我还没有处理完或者我还没有应答你,你先别分配给我,我目前只能处理一个 任务,然后 rabbitmq 就会把该任务分配给没有那么忙的那个空闲消费者,当然如果所有的消费者都没有完 成手上任务,队列还在不停的添加新任务,队列有可能就会遇到队列被撑满的情况,这个时候就只能添加 新的 worker 或者改变其他存储任务的策略。

四、预取值

本身消息的发送就是异步发送的,所以在任何时候,channel 上肯定不止只有一个消息,另外来自消费 者的手动确认本质上也是异步的。因此这里就存在一个未确认的消息缓冲区,因此希望开发人员能限制此 缓冲区的大小,以避免缓冲区里面无限制的未确认消息问题。

这个时候就可以通过使用 basic.qos 方法设 置“预取计数”值来完成。该值定义通道上允许的未确认消息的最大数量。一旦数量达到配置的数量, RabbitMQ 将停止在通道上传递更多消息,除非至少有一个未处理的消息被确认。

设置预取值的方式和三中一样,即channel.basicQos(预取值)。

例如,假设在通道上有 未确认的消息 5、6、7,8,并且通道的预取计数设置为 4,此时 RabbitMQ 将不会在该通道上再传递任何 消息,除非至少有一个未应答的消息被 ack。比方说 tag=6 这个消息刚刚被确认 ACK,RabbitMQ 将会感知 这个情况并再发送一条消息。

rabbitmq 队列持久化,java,Linux,rabbitmq,java,消息队列,Powered by 金山文档

消息应答和 QoS 预取值对用户吞吐量有重大影响。通常,增加预取值将提高 向消费者传递消息的速度。虽然自动应答传输消息速率是最佳的,但是,在这种情况下已传递但尚未处理 的消息的数量也会增加,从而增加了消费者的 RAM 消耗(随机存取存储器)。应该小心使用具有无限预处理 的自动确认模式或手动确认模式,消费者消费了大量的消息如果没有确认的话,会导致消费者连接节点的 内存消耗变大,所以找到合适的预取值是一个反复试验的过程,在不同的负载下该值取值也不同,100 到 300 范 围内的值通常可提供最佳的吞吐量,并且不会给消费者带来太大的风险。预取值为 1 是最保守的。当然这 将使吞吐量变得很低,特别是消费者连接延迟很严重的情况下,特别是在消费者连接等待时间较长的环境 中。对于大多数应用来说,稍微高一点的值将是最佳的。 文章来源地址https://www.toymoban.com/news/detail-601582.html

到了这里,关于RabbitMQ学习(五):RabbitMQ持久化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RabbitMQ学习(五):RabbitMQ持久化

    在上一章内容中我们已经看到了如何处理任务不丢失的情况,但是如何保障当 RabbitMQ 服务停掉后消 息生产者发送过来的消息不丢失呢?默认情况下 RabbitMQ 退出或由于某种原因崩溃时,它将忽视队列 和消息,除非告知它不要这样做。 确保消息不会丢失需要做两件事:我们需

    2024年02月16日
    浏览(39)
  • 【RabbitMQ笔记08】消息队列RabbitMQ之防止消息丢失的三种方式(生产者消息确认、消费者消息确认、消息持久化)

    这篇文章,主要介绍消息队列RabbitMQ之防止消息丢失的三种方式(生产者消息确认、消费者消息确认、消息持久化)。 目录 一、防止消息丢失 1.1、消息确认机制(生产者) (1)生产者丢失消息 (2)生产者消息确认机制 1.2、消息确认机制(消费者) (1)消费者丢失消息

    2024年02月02日
    浏览(48)
  • RabbitMQ-数据持久化

    1、交换机持久化(SpringAMQP默认) 2、队列持久化(SpringAMQP默认) 3、消息持久化         如果采用纯内存操作,那么消息存储达到队列的上限之后,会有一个page out操作,这个操作是将队列中已经有的一部分MQ消息转移到磁盘,给队列腾出空间,使得队列能够继续接收MQ消息

    2024年01月21日
    浏览(42)
  • RabbitMQ 持久化

      通过持久化可以 尽量 防止在RabbitMQ异常情况下(重启、关闭、宕机)的数据丢失。持久化技术是解决消息存储到队列后的丢失问题,但是通过持久化并不能完全保证消息不丢失。   持久化技术可以分为交换机持久化、队列持久化以及消息持久化,它们的实现方案和实

    2024年02月12日
    浏览(39)
  • RabbitMQ---持久化

    • 如何避免消息丢失? 1) 消费者的ACK机制。可以防止消费者丢失消息。 2) 但是,如果在消费者消费之前,MQ就宕机了,消息就没了。 • 如何将消息进行持久化呢? 要将消息持久化,前提是:队列、Exchange都持久化

    2024年02月11日
    浏览(43)
  • 【RabbitMQ】之持久化机制

    一、RabbitMQ 持久化机制 1、RabbitMQ 持久化概述 2、队列持久化 3、消息持久化 4、交换器持久化 二、RabbitMQ 知识扩展 1、内存告警与内存换页 2、磁盘告警与配置 3、数据写入磁盘时机 4、磁盘消息格式 5、磁盘文件删除机制 持久化 ,即将原本存在于内存中的数据写入到磁盘上永

    2024年02月14日
    浏览(38)
  • 【初始RabbitMQ】持久化的实现

    如何保障当 RabbitMQ 服务停掉以后消 息生产者发送过来的消息不丢失。默认情况下 RabbitMQ 退出或由于某种原因崩溃时,它忽视队列 和消息,除非告知它不要这样做。确保消息不会丢失需要做两件事: 我们需要将队列和消息都标记为持久化 之前我们创建的队列都是非持久化的

    2024年02月19日
    浏览(34)
  • 【RabbitMQ 实战】10 消息持久化和存储原理

    rabbitmq的持久化分为三个部分: 交换器的持久化。 队列的持久化。 消息的持久化。 1.1.1 交换器持久化 交换器的持久化是通过在声明交换器时, 指定Durability参数为durable实现的。 若交换器不设置持久化,在rabbitmq服务重启之后,相关的交换器元数据会丢失,但消息不会丢失,

    2024年02月07日
    浏览(40)
  • RabbitMQ (HelloWord 消息应答 持久化 不公平分发 预取值)

    在下图中,“P”是我们的生产者,“C”是我们的消费者。中间的框是一个队列-RabbitMO.代表使用者保留的消息缓冲区 第一步:导入依赖 第二步:创建生产者 第三步:创建消费者 因为你为了确保同一条消息被其中一个工作线程接收到了之后,其它工作就不能消费的到了 三者

    2023年04月14日
    浏览(40)
  • SpringBoot-RabbitMQ06-持久化和ACK确认机制

    1.什么是消息确认ACK? 如果在处理消息的过程中,消费者的服务器在处理消息时出现异常,那么可能这条正在处理的消息刘没有完成消息消费,数据就会丢失,为了确保数据不会丢失RabbitMQ支持消息确认-ACK 2.ACK的消息确认机制 ACK机制是消费者从RabbitMQ收到消息并处理完成后,反

    2024年04月15日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包