前言

上一节我们简单介绍了RabbitMQ和在安装后启动所出现的问题,本节我们开始正式进入RabbitMQ的学习,对于基本概念请从官网或者其他前辈博客上查阅,我这里不介绍基础性东西,只会简单提一下,请知悉。

RabbitMQ持久化

在RabbitMQ中存在四种交换机,一是直连交换机(Direct Exchange),二是广播交换机(Fantout Exchange),三是主题交换机(Topic Exchange),四是头交换机(Header Exchange),每种交换机都有其对应场景,后面会一一讲到。任何处理消息的开源库都离不开两个角色,一是生产者(Producer),二是消费者(Consumer),消息从生产者到达消费者需经过三个阶段也就是我们需要知道的三个概念,一是交换机,二是队列,三是绑定,初次见此三者概念感觉很高大上是不是,其实不过是高度抽象了而已,同时看到很多博客上对此三者解释的还是非常深刻,我这里就不过多细说。我们先看别人博客上对整个RabbitMQ架构用图来进行标识,然后对照我对交换机、队列、绑定一言以蔽之进行如下概括您就明白他们具体是干什么了。

交换机是生产者发布消息的入口点,队列是消费者获取消息的容器,绑定是将交换机连接到队列的规则

我们简单过一下消息从生产者到达消费者的大概过程,生产者也就是上述图中的ClientA和ClientB,发送消息到交换机,这里交换机可以是一个或者多个,然后通过路由键绑定到队列,那么消费者如何知道绑定到了哪个队列呢?然后消费者也就是上述Client1、Client2、Client3也要声明交换机、队列、绑定,这样整个过程就串起来了,原理大概就是这样。接下来我们通过代码来实现生产者发送消息(请通过NuGet安装RabbitMQ客户端)。

    public class RabbitMQService
{
public IConnection GetRabbitMQConnection()
{
var connectionFactory = new ConnectionFactory
{
HostName = "localhost",
UserName = "guest",
Password = "guest"
};
return connectionFactory.CreateConnection();
}
}

第一步当然是需要创建连接,连接到RabbitMQ服务,接下来则是在我们创建连接的基础上创建通道,然后上述我们所说消息从生产者到达消费者的过程就是在此通道上进行。

            var rabbitMQService = new RabbitMQService();
var connection = rabbitMQService.GetRabbitMQConnection();
var model = connection.CreateModel();

接下来则是声明交换机、队列、通过路由键将交换机和队列绑定在一起。

        static void InitialTopicQueue(IModel model)
{
model.QueueDeclare("queueDeclare", true, false, false, null);
model.ExchangeDeclare("exchangeDeclare", ExchangeType.Topic);
model.QueueBind("queueDeclare", "exchangeDeclare", "routeKey");
}

如上我们声明队列名称为queueDeclare且该队列持久化,然后声明交换机名称为exchangeDeclare,交换机类型为主题,最后通过QueueBind方法通过routekey路由键将声明的交换机和队列绑定在一起。接下来我们开始发布消息。

            var basicProperties = model.CreateBasicProperties();
basicProperties.DeliveryMode = ;
var payload = Encoding.UTF8.GetBytes("这是来自运行VS2017控制台发出的消息");
var address = new PublicationAddress(ExchangeType.Topic, "exchangeDeclare", "routeKey");
model.BasicPublish(address, basicProperties, payload);

然后我们在控制台中运行上述程序,然后在RabbitMQ UI上来查看声明的交换机、队列、绑定的路由键以及承载的消息。

一切如正常运行,其我们发布的消息在队列中处于Ready状态,接下来我们在服务中关闭RabbitMQ服务代理,然后重启模拟宕机的情况。

因为在声明队列中第二个参数可指定该队列是否可持久化,我们指定为True即持久化,所以即使RabbitMQ Broker重启队列依然还在,这个时候我们会发现在队列中的数据被扔掉了,也就是说此时的队列为空。那是因为我们指定消息为非持久化,如下指定传输模式即DeliveryModel属性为1,1代表非持久化,2为可持久化。所以如果我们指定DeliveryMode等于2即使RabbitMQ代理宕机,重启后消息依然还在。

            var basicProperties = model.CreateBasicProperties();
basicProperties.DeliveryMode = ;

同理切换到ExchangeType界面时,此时我们声明的交换机不存在了,如下:

因为声明交换机时ExchangeDeclare方法有重载,第三个参数可指定是否持久化,默认为非持久化,如果我们进行如下指定为持久化,那么和在队列中的消息一样即使RabbitMQ代理重启交换机依然还在,这个就不需要我再过多啰嗦了。

 model.ExchangeDeclare("exchangeDeclare", ExchangeType.Topic, true);

从如上演示我们可看出在RabbitMQ中关于持久化,可对交换机(ExChange)、队列(Queue)、消息(Message)分别指定持久化,而且在大部分情况下这也是我们想要的。因为这至少可以保证消息从生产者传递消费者的过程中不会丢失。那么对于持久化和非持久化RabbitMQ是如何进行处理的呢?

持久化:将消息保存到磁盘上,因此即使在服务器重新启动后它们仍然可用,只不过在读取和保存消息时会产生一些额外的开销罢了。

非持久化:将消息被保存在内存中,虽然它们在服务器重启后将会消失,但提供更快的消息处理。

总结

今天我们详细讲解了RabbitMQ中的持久化,我们可从交换机、队列、消息三个层面去设置持久化。这只是小试牛刀,下节开始讨论细枝末节,学习的过程也是发现问题的过程,我们下节再会。

学习在.NET Core中使用RabbitMQ进行消息传递之持久化(二)的更多相关文章

  1. 在ABP core中使用RabbitMq

    距上一篇博客的更新一集很久了,主要是最近做的事情比较杂,中间也有一个难点,就是在ABP中加入APP扫码登录,本来想些的,但是觉得这个写出来会不会让我们的系统被破解-_-||,所以想了想,就没有写. 这 ...

  2. .NET Core中使用RabbitMQ正确方式

    .NET Core中使用RabbitMQ正确方式 首先甩官网:http://www.rabbitmq.com/ 然后是.NET Client链接:http://www.rabbitmq.com/dot ...

  3. WSL2+Docker部署RabbitMQ以及在Asp.net core 中使用RabbitMQ示例(1)

    本文主要在于最近因疫情不能外出,在家研究的一些技术积累. 主要用到的技术以及知识点: WSL 2 WSL 2+Docker Docker+RabbitMQ 在ASP.NET Core中使用Rabbit ...

  4. 3、带你一步一步学习ASP.NET Core中的配置之Configuration

    如果你是刚接触ASP.NET Core的学习的话,你会注意到:在ASP.NET Core项目中,看不到.NET Fraemwork时代中的web.config文件和app.config文件了.那么你肯 ...

  5. 在.Net Core中使用MongoDB的入门教程(二)

    在上一篇文章中,讲到了MongoDB在导入驱动.MongoDB的连接,数据的插入等. 在.Net Core中使用MongoDB的入门教程(一) 本篇文章将接着上篇文章进行介绍MongoDB在.Net ...

  6. SpringBoot学习笔记(11)-----SpringBoot中使用rabbitmq,activemq消息队列和rest服务的调用

    1. activemq 首先引入依赖 pom.xml文件 <dependency> <groupId>org.springframework.boot</groupId& ...

  7. DotNet Core中使用RabbitMQ

    上一篇随笔记录到RabbitMQ的安装,安装完成,我们就开始使用吧. RabbitMQ简介 AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协 ...

  8. .Net Core中使用RabbitMQ

    (1).引入依赖 RabbitMQ.Client (2).编写发布者代码 var connectionFactory = new ConnectionFactory() { HostName=&quo ...

  9. 在.Net Core中使用MongoDB的入门教程(一)

    首先,我们在MongoDB的官方文档中看到,MongoDb的2.4以上的For .Net的驱动是支持.Net Core 2.0的. 所以,在我们安装好了MangoDB后,就可以开始MangoDB的.N ...

随机推荐

  1. 关于vertical-align和line-height的真知灼见

    本文的重点是了解vertical-align和line-height的使用 涉及到的名词:基线,底端,行内框,行框,行间距,替换元素及非替换元素,对齐.只有充分理解这些概念才会灵活运用这两个属性. 什 ...

  2. Struts(二十):自定义类型转换器

    如何自定义类型转换器: 1)为什么需要自定义类型转化器?strtuts2不能自动完成字符串到所有的类型: 2) 如何定义类型转化器? 步骤一:创建自定义类型转化器的类,并继承org.apache.st ...

  3. hdu1728 逃离迷宫---转弯次数不超过k+BFS

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1728 题目大意: 给你一幅图,给出起点终点和最大转弯次数,判断是否能从起点到终点.'*'表示障碍物. ...

  4. vuex commit保存数据技巧

    vuex 单向数据流,推荐的commit 改变state数据,写起来非常繁琐,因为改数据可能要写很多commit函数. 依据我的理解,单向数据流主要是为了避免数据混乱,便于调试. 说白了,就是一个数据 ...

  5. 远程连接服务器jupyter notebook、浏览器以及深度学习可视化方法

    h1 { counter-reset: h2counter; } h2 { counter-reset: h3counter; } h3 { counter-reset: h4counter; } h ...

  6. 文件上传详解 (HTML FILE)

    FileUpload 对象 在 HTML 文档中 <input type="file"> 标签每出现一次,一个 FileUpload 对象就会被创建. 该元素包含一个文 ...

  7. DDD实战进阶第一波(五):开发一般业务的大健康行业直销系统(实现产品上下文领域层)

    从这篇文章开始,我们根据前面的DDD理论与DDD框架的约束,正式进入直销系统案例的开发. 本篇文章主要讲产品上下文中的领域层的主要实现,先简单讲下业务方面的需求:产品SPU与产品SKU,产品SPU主要 ...

  8. [LeetCode] Minimum Time Difference 最短时间差

    Given a list of 24-hour clock time points in "Hour:Minutes" format, find the minimum minut ...

  9. spring data jpa 组合条件查询封装

    /** * 定义一个查询条件容器 * @author lee * * @param <T> */ public class Criteria<T> implements Spe ...

  10. 《C++ Primer》学习笔记:迭代器介绍

    <C++Primer>(第五版)中,3.4.1的例题中使用一个名为text的字符串向量存放文本文件中的数据,输出text中的内容,刚开始我这样写: #include <iostrea ...