rabbitmq 持久化_RabbitMQ原理与相关操作(三)消息持久化

现在聊一下RabbitMQ消息持久化:

问题及方案描述

1.当有多个消费者同时收取消息,且每个消费者在接收消息的同时,还要处理其它的事情,且会消耗很长的时间。在此过程中可能会出现一些意外,比如消息接收到一半的时候,一个消费者死掉了。

这种情况要使用消息接收确认机制,可以执行上次宕机的消费者没有完成的事情。

2.在默认情况下,我们程序创建的消息队列以及存放在队列里面的消息,都是非持久化的。当RabbitMQ死掉了或者重启了,上次创建的队列、消息都不会保存。

这种情况可以使用RabbitMQ提供的消息队列的持久化机制。

相关理论描述

RabbitMQ支持消息的持久化,也就是数据写在磁盘上,为了数据安全考虑,我个人觉得大多数开发人员都会选择持久化。

队列和交换机有一个创建时候指定的标志durabledurable的唯一含义就是具有这个标志的队列和交换机会在重启之后重新建立,它不表示说在队列当中的消息会在重启后恢复。

消息队列持久化包括3个部分:

1、exchange持久化,在声明时指定durable => true2、queue持久化,在声明时指定durable => true3、消息持久化,在投递时指定delivery_mode=> 2(1是非持久化)

如果exchange和queue都是持久化的,那么它们之间的binding也是持久化的。如果exchange和queue两者之间有一个持久化,一个非持久化,就不允许建立绑定。

注意:一旦创建了队列和交换机,就不能修改其标志了。例如,如果创建了一个non-durable的队列,然后想把它改变成durable的,唯一的办法就是删除这个队列然后重现创建

程序示例

生产者

class Producter    {        const string ExchangeName = "eric.exchange";        const string QueueName = "eric.queue";        static void Main(string[] args)        {            var factory = new ConnectionFactory() { HostName = "localhost", UserName = "eric", Password = "123456", };            using (var connection = factory.CreateConnection())            using (var channel = connection.CreateModel())            {                channel.ExchangeDeclare(ExchangeName, "direct", durable: true, autoDelete: false, arguments: null);//声明消息队列,且为可持久化的                channel.QueueDeclare(QueueName, durable: true, exclusive: false, autoDelete: false, arguments: null);//声明消息队列,且为可持久化的                channel.QueueBind(QueueName, ExchangeName, routingKey: QueueName);                string message = "Eric is very handsome";                var body = Encoding.UTF8.GetBytes(message);                //将队列设置为持久化之后,还需要将消息也设为可持久化的                var props = channel.CreateBasicProperties();                props.SetPersistent(true);                channel.BasicPublish(ExchangeName, routingKey: QueueName, basicProperties: props, body: body);                Console.WriteLine("Producter Sent: {0}", message);                Console.ReadKey();            }        }    }

注:ack是 acknowledgments 的缩写,noAck 是("no manual acks")

因为我前段时间换了笔记本,所以用户的“eric”的操作出踩了个坑,下面进行介绍下:

如果调试运行时报错:None of the specified endpoints were reachable

innerException是:

{"The AMQP operation was interrupted: AMQP close-reason, initiated by Library, code=541, text="Unexpected Exception", classId=0, methodId=0, cause=System.IO.IOException: 无法从传输连接中读取数据: 远程主机强迫关闭了一个现有的连接。。 ---> System.Net.Sockets.SocketException: 远程主机强迫关闭了一个现有的连接。   在 System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)   在 System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)   --- 内部异常堆栈跟踪的结尾 ---   在 RabbitMQ.Client.Impl.Frame.ReadFrom(NetworkBinaryReader reader)   在 RabbitMQ.Client.Impl.SocketFrameHandler.ReadFrame()   在 RabbitMQ.Client.Framing.Impl.Connection.MainLoopIteration()   在 RabbitMQ.Client.Framing.Impl.Connection.MainLoop()"}

这说明我们使用的用户 不是 系统默认的 guest 而是我们自己创建的用户,但是没有足够的权限进行操作。

解决办法:

rabbitmqctl set_user_tags username administratorrabbitmqctl set_permissions -p / username ".*" ".*" ".*"

执行结果:

2df5b5ca92515bb501d64bc2dd1bc93a.png

相关其他操作见:windows下 安装 rabbitMQ 及操作常用命令

程序运行结果:

431e9d5e7b9e325e202bdb189bbb5e1d.png

消费者

class Recevice    {        const string ExchangeName = "eric.exchange";        const string QueueName = "eric.queue";        public static void Main()        {            var factory = new ConnectionFactory() { HostName = "localhost", UserName = "eric", Password = "123456", VirtualHost = "/" };            using (var connection = factory.CreateConnection())            using (var channel = connection.CreateModel())            {                channel.ExchangeDeclare(ExchangeName, "direct", durable: true, autoDelete: false, arguments: null);//声明消息队列,且为可持久化的                channel.QueueDeclare(QueueName, durable: true, exclusive: false, autoDelete: false, arguments: null);//声明消息队列,且为可持久化的                channel.QueueBind(QueueName, ExchangeName, routingKey: QueueName);                BasicGetResult msgResponse = channel.BasicGet(QueueName, noAck: true);                //NoAck:true 告诉RabbitMQ立即从队列中删除消息,另一个非常受欢迎的方式是从队列中删除已经确认接收的消息,可以通过单独调用BasicAck 进行确认:                //BasicGetResult msgResponse = channel.BasicGet(QueueName, noAck:false);                var msgContent = Encoding.UTF8.GetString(msgResponse.Body);                Console.WriteLine("The received content:"+msgContent);                channel.BasicAck(msgResponse.DeliveryTag, multiple: false);                //使用BasicAck方式来告之是否从队列中移除该条消息                //需要额外注意,比如从队列中获取消息并用它来操作数据库或日志文件时,如果出现操作失败时,则该条消息应该保留在队列中,只到操作成功时才从队列中移除。                Console.ReadKey();            }        }    }

接受消息还有一种方法,就是通过基于推送的事件订阅。可以使用内置的 QueueingBasicConsumer 提供简化的编程模型,允许在共享队列上阻塞,直到收到一条消息。

var consumer = new QueueingBasicConsumer(channel);                channel.BasicConsume(QueueName, noAck: true, consumer: consumer);                var msgResponse = consumer.Queue.Dequeue();                 var msgContent = Encoding.UTF8.GetString(msgResponse.Body);

程序运行结果:

dd7ac9d12cc7b2d7ff193e208c561ff1.png

原文链接:https://www.cnblogs.com/ericli-ericli/p/5938106.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/501144.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视图的数据存放在哪里_分布式 | DBLE 是如何实现视图的?

作者:苏仕祥浩鲸科技 PaaS 组件团队成员,长期从事分库分表中间件的相关解决方案工作,热爱技术,乐于分享。本文来源:原创投稿*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并…

IOC操作Bean管理注解方式(注入属性@Autowired和Qualifier)

目录 IOC操作Bean管理注解方式(注入属性Autowired、Qualifier和Resource) 1.基于注解方式实现 属性注入 (1)Autowired:根据属性类型进行自动装配 第一步: 第二步: (2&#xff…

python数据可视化的特点_6 种 Python 数据可视化工具

原标题:6 种 Python 数据可视化工具 英文:Chris Moffitt,编译:伯乐在线/李加庆 简介 在 Python 中,将数据可视化有多种选择,正是因为这种多样性,何时选用何种方案才变得极具挑战性。本文包含了一…

IOC操作Bean管理注解方式(完全注解开发)

IOC操作Bean管理注解方式(完全注解开发) (1)创建配置类,替代xml配置文件 需要让Spring 把一个普通的类认为是配置类 结构图: SpringConfig类代码如下: package com.lbj.spring5.comfig;import …

Spring的AOP-基本概念

AOP-基本概念 Aspect Oriented Programming:面向切面编程,利用AOP 可以对业务逻辑的各个部分进行隔离。从而使得业务逻辑各部分之间的 “ 耦合度降低 ” 通俗解释:在不修改原有代码的情况下增加功能而不影响原有功能,在主干功能里…

为什么python打不开_python文件打不开如何解决

python中打开文件使用的是open()函数,获取文件对象,之后的操作都是相对于文件对象而言的。f open(your_file.txt,r) 就可以打开一个文件进行操作。第二个参数为对文件的操作方式,’w’是写文件,已存在的同名文件会被清空&#xf…

Spring的AOP-底层原理

目录 1.有两种动态代理 第一种:有接口情况,使用JDK动态代理 第二种:无接口情况,使用CGLIB动态代理 2.使用JDK动态代理,使用Proxy类里面的方法创建代理对象 步骤一: 步骤二: 步骤三&#…

screnc加密后文件不能执行_芯片加密后还能不能再次使用【详细介绍】

随着信息技术的发展,信息的载体-芯片的运用也越来越多了,随之而来的芯片安全性的要求也越来越高了,各个芯片厂商对芯片保密性要求越来越高,芯片的加密,保证了芯片中的信息的安全性。经常有客户打电话过来问&#xff0c…

Spring的AOP-操作术语

目录 Spring的AOP-操作术语 1.连接点 2.切入点 3.通知 (1)实际增强的逻辑部分称为通知 (2)通知有多种类型 4.切面 Spring的AOP-操作术语 1.连接点 类里面那些方法可以被增强,这些方法称为连接点 2.切入点 类里…

向别人网页注入js_区块链研究实验室 | Web3 .js基于以太坊的Javascript API

web3.js是一个库集合,你可以使用HTTP或IPC连接本地或远程以太它节点进行交互。 web3的JavaScript库能够与以太坊区块链交互。 它可以检索用户帐户,发送交易,与智能合约交互等。Version : 1.0.0-beta.36Web3.js API类型eth:Etherum…

Spring的AOP-准备工作

目录 Spring的AOP-准备工作 1.Spring框架一般基于 AspectJ 实现AOP操作 2.基于AspectJ 实现 AOP 操作 (1)基于xml 配置文件实现 (2)基于注解方式实现【常用】 3.在项目工程用引入AOP 相关依赖 步骤一:找到依赖包…

Spring的AOP-AspectJ注解方式

目录 Spring的AOP-AspectJ注解方式 1.创建类,在类里面定义方法 2.创建增强类 3.进行通知的配置 (1)在Spring 配置文件中,开启直接扫描 (2)使用注解创建User 和 UserProxy 对象 (3&#x…

python turtle绘制柱状图_python绘制图形(Turtle模块)

用python的Turtle模块可以绘制很多精美的图形,下面简单介绍一下使用方法。 需要用到的工具有python,python 的安装这里就不再细说。自行搜索。 from turtle import * #引入turtle模块 color(red, yellow) #设置绘制的颜色和填充颜色 # 海龟设置 hideturt…

JdbcTemplate(概念和准备)

目录 1.什么是jdbcTemplate 2.使用前准备工作: (1)引入相关jar包 (2)在spring 配置文件配置数据库连接池​ (3)配置jdbcTemplate 对象,注入 DataSource (4&#xf…

python shape函数_Python中的多态及抽象类

本书同名免费MOOC《Python编程基础及应用》在哔哩哔哩(B站)热播,作者带着你学。版权声明:本文内容引用自作者的图书《Python编程基础及应用》(高等教育出版社)。本文可以在互联网上转载传播,但必须包含文中的版权声明;本文不可以以…

JdbcTemplate(操作数据库-添加功能)

目录 JdbcTemplate(操作数据库-添加功能) 1.建立数据库表: 2.对应数据库创建实体类: 3.编写service 和 dao (1)在 dao 层进行数据库添加操作 (2)具体:调用jdbcTemp…

JdbcTemplate(操作数据库-修改和删除功能)

目录 JdbcTemplate(操作数据库-删除功能) 1.创建数据库 2.配置文件实现 3.创建实体类 4.创建dao层 5.创建service层 6.测试类 7.测试结果: JdbcTemplate(操作数据库-删除功能) 1.创建数据库 user_db数据库的t_…

单片机定时器实验两位倒计时秒表_51单片机基础与应用8天速成(三)

在讲授中断这一概念时,人们总是喜欢举洗衣服烧水的例子:话说,一天“你”独自在家,为了泡脚给自己烧上了一壶水,然后想着明天没有衣服穿了,就去阳台洗起了衣服。过了十几分钟,“你”在阳台洗着衣…

JdbcTemplate(操作数据库-查询返回值)

目录 JdbcTemplate(操作数据库-查询返回值) 1.创建数据库 2.创建实体类 3.创建dao层 4.创建service层 5.创建测试类: 6.xml配置 7.测试结果: 8.结构示意: JdbcTemplate(操作数据库-查询返回值&…

c++opencv显示中文_OpenCV安装,配置和运行

今天小崔有个项目功能想用OpenCV软件库实现一下,就安装了OpenCV,在这里给大家分享一下安装过程。一.什么是OpenCV OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。 它轻量…