C#/.Net集成RabbitMQ
RabbitMQ简介
消息 (Message) 是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串、 JSON 等,也可以很复杂,比如内嵌对象。
消息队列中间件 (Message Queue Middleware,简称为 MQ) 是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展进程间的通信。
消息队列中间件,也可以称为消息队列或者消息中间件。它一般有两种传递模式:点对点 (P2P, Point-to-Point) 模式和发布/订阅 (Pub/Sub) 模式。点对点模式是基于队列的,消息生产者发送消息到队列,消息消费者从队列中接收消息,队列的存在使得消息的异步传输成为可能。 发布订阅模式定义了如何向一个内容节点发布和订阅消息,这个内容节点称为主题 (topic),主题可以认为是消息传递的中介,消息发布者将消息发布到某个主题,而消息订阅者则从主题中订阅消息。主题使得消息的订阅者与消息的发布者互相保持独立,不需要进行接触即可保证消息的传递,发布/订阅模式在消息的一对多广播时采用 。
RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库。
关于RabbitMQ的原理及详细介绍百度上很多,这里就不做复制粘贴了。
生产者和消费者
在使用RabitMQ之前,先对几个概念做一下说明:
生产者(Producer):
生产者就是投递消息的一方。生产者创建消息,然后发布到 RabbitMQ 中。消息一般可以包含2个部分:消息体和标签 (Label)。消息体也可以称之为 payload,在实际应用中,消息体一般是一个带有业务逻辑结构的数据,比如一个JSON字符串。当然可以进一步对这个消息体进行序列化操作。消息的标签用来表述这条消息 ,比如一个交换器的名称和一个路由键。生产者把消息交由RabbitMQ,RabbitMQ之后会根据标签把消息发送给感兴趣的消费者 (Consumer)。
消息中间件的服务节点(Broker)
对于RabbitMQ来说,一个RabbitMQ Broker可以简单地看作一个RabbitMQ服务节点 ,或者RabbitMQ服务实例 。大多数情况下也可以将一个RabbitMQ Broker看作一台RabbitMQ服务器。
首先生产者将业务方数据进行可能的包装, 之后封装成消息, 发送 (AMQP 协议里这个动 作对应的命令为 Basic . Publish) 到 Broker 中 。 消费者订阅并接收消息 (AMQP 协议里这个动作对应的命令为 Basic.Consurne 或者 Basic. Get),经过可能的解包处理得到原始的数据, 之后再进行业务处理逻辑。这个业务处理逻辑并不一定需要和接收消息的逻辑使用同一个线程。 消费者进程可以使用一个线程去接收消息,存入到内存中。业务处理逻辑使用另一个线程从内存中读取数据,这样可以将应用进一步解稿,提高整个应用的处理效率。
队列(Queue)
队列,是RabbitMQ的内部对象,用于存储消息。RabbitMQ中消息都只能存储在队列中,RabbitMQ的生产者生产消息井最终技递到队列中,消费者可以从队列中获取消息并消费。多个消费者可以订阅同一个队列,这时队列中的消息会被平均分摊(Round-Robin,即轮询) 给多个消费者进行处理,而不是每个消费者都收到所有的消息井处理。
消费者(Consumer)
消费者,就是接收消息的一方。消费者连接到RabbitMQ服务器,并订阅到队列上。当消费者消费一条消息时,只是消费消息的消息体 (payload)。在消息路由的过程中,消息的标签会丢弃,存入到队列中的消息只 有消息体,消费者也只会消费到消体,也就不知道消息的生产者是谁,当然消费者也不需要知道。
项目中集成MQ
首先先安装好RabbitMQ,可以参考我之前写的教程 https://blog.csdn.net/yindi0712/article/details/107544076
1.这里我创建了一个Mvc项目作为生产者端,一个控制台作为消费者端
2.两个项目分别引用RabbitMQ.Client.dll,可以在官网下载:
下载地址:http://www.rabbitmq.com/releases/rabbitmq-dotnet-client/
也可以直接从Nuget中安装,二者效果是一样的
我这边选择用Nuget安装。
3.简单集成,实现消息生产和消费
生产者端
我这边创建了个简单的mvc项目,引用RabbitMQ.Client.dll,在HomeController创建一个名为Send的Action
public ActionResult Send(SendModel model)
{
//实例化一个连接工厂和其配置为使用所需的主机,虚拟主机和证书(证书)
ConnectionFactory factory = new ConnectionFactory();
factory.HostName = model.Url;//RabbitMQ主机服务地址
factory.UserName = model.UserName;//用户名
factory.Password = model.Password;//密码
//创建一个AMQP 0-9-1连接
using (IConnection connection = factory.CreateConnection())
{
//创建一个AMQP 0-9-1频道,该对象提供了大部分 的操作(方法)协议。
using (IModel channel = connection.CreateModel())
{
channel.QueueDeclare(model.Queue, false, false, false, null);//创建一个名称消息队列
string message = model.Content; //传递的消息内容
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish("", model.Queue, null, body); //开始传递
}
}
return RedirectToAction("index");
}
消费者端
我这里创建了一个控制台应用,同样引用RabbitMQ.Client.dll,消费的逻辑直接写在Main方法里了
static void Main(string[] args)
{
//实例化一个连接工厂和其配置为使用所需的主机,虚拟主机和证书(证书)
ConnectionFactory factory = new ConnectionFactory();
factory.HostName = "127.0.0.1";//RabbitMQ主机服务地址
factory.UserName = "test";//用户名
factory.Password = "testpwd";//密码
//创建一个AMQP 0-9-1连接
using (IConnection connection = factory.CreateConnection())
{
//创建一个AMQP 0-9-1频道,该对象提供了大部分 的操作(方法)协议。
using (IModel channel = connection.CreateModel())
{
channel.QueueDeclare("getMessage", false, false, false, null);//声明一个名称消息队列
EventingBasicConsumer consumer = new EventingBasicConsumer(channel);//创建一个消费者实现c#事件处理程序实例
channel.BasicConsume("getMessage", false, consumer);//开始消费
//消息到达消费者时触发的事件
consumer.Received += (model, ea) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body.ToArray());
Console.WriteLine("已接收: {0}", message);
};
Console.ReadLine();
}
}
}
总结:
1.首先不管是消费者还是生产者都要先创建一个连接工厂ConnectionFactory配置连接的基本信息;
2.通过ConnectionFactory.CreateConnection创建一个IConnection对象表示创建一个AMQP 0-9-1连接;
3.IConnection.CreateModel创建一个AMQP 0-9-1频道,该对象提供了大部分 的操作(方法)协议;
4.使用IModel.QueueDeclare声明一个消息队列,生产者和消费者的队列名称要一致;
5.生产者端:使用IModel.BasicPublish发送消息到消息队列;
6.消费者端:创建一个消费者事件对象EventingBasicConsumer;使用IModel.BasicConsume将该消费者启动,在消息接收触发事件EventingBasicConsumer.Received做后续操作。
至此一个简单的消费者和生产者端就搭建好了,下面我们运行起来看一下效果:
上面是我本地的配置信息,下面我创建一个getMessage队列并发送一条123的消息。
我们直接进管理界面看吧,就不敲命令了,如果本地装了管理插件直接访问http://127.0.0.1:15672/,我们先进到Queues,我们可以看到刚刚创建的getMessage队列
然后进入到队列内部,去点一下GetMessages按钮:
我们可以看到刚才发送的123已经在队列中了,现在我们运行消费者端
我们可以看到这个消息已经输出出来了,这时候再去点击GetMessages,这时候就会提示Queue is empty,表示该消息已经消费了。可以把两个项目同时运行,多发几条消息基本上是事实的。
————————————————————————————————————————————————————
今天先写到这,后面再说说响应机制集群幂等性啥的
C#/.Net集成RabbitMQ的更多相关文章
- rabbitMQ第五篇:Spring集成RabbitMQ
前面几篇讲解了如何使用rabbitMq,这一篇主要讲解spring集成rabbitmq. 首先引入配置文件org.springframework.amqp,如下 <dependency> ...
- RabbitMQ第四篇:Spring集成RabbitMQ
前面几篇讲解了如何使用rabbitMq,这一篇主要讲解spring集成rabbitmq. 首先引入配置文件org.springframework.amqp,如下 <dependency> ...
- springboot集成rabbitmq(实战)
RabbitMQ简介RabbitMQ使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现(AMQP的主要特征是面向消息.队列.路由.可靠性.安全).支持多种客户端,如:Python.Ru ...
- SpringBoot集成rabbitmq(二)
前言 在使用rabbitmq时,我们可以通过消息持久化来解决服务器因异常崩溃而造成的消息丢失.除此之外,我们还会遇到一个问题,当消息生产者发消息发送出去后,消息到底有没有正确到达服务器呢?如果不进行特 ...
- SpringBoot集成rabbitmq(一)
前言 Rabbitmq是一个开源的消息代理软件,是AMQP协议的实现.核心作用就是创建消息队列,异步发送和接收消息.通常用来在高并发中处理削峰填谷.延迟处理.解耦系统之间的强耦合.处理秒杀订单. 入 ...
- Spring Boot系列——7步集成RabbitMQ
RabbitMQ是一种我们经常使用的消息中间件,通过RabbitMQ可以帮助我们实现异步.削峰的目的. 今天这篇,我们来看看Spring Boot是如何集成RabbitMQ,发送消息和消费消息的.同时 ...
- SpringBoot集成RabbitMQ消息队列搭建与ACK消息确认入门
1.RabbitMQ介绍 RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性.扩展性.高可用性等方面表现不俗.Rabbi ...
- RabbitMQ(3) Spring boot集成RabbitMQ
springboot集成RabbitMQ非常简单,如果只是简单的使用配置非常少,springboot提供了spring-boot-starter-amqp项目对消息各种支持. 资源代码:练习用的代码. ...
- 集成RabbitMQ做秒杀
由于秒杀的并发量太大,所以仅仅使用缓存是不够的,还需要用到RabbitMQ. 这里推荐一款用于分库分表的中间件:mycat 解决超卖的问题(看第五章节): 秒杀接口优化: 实操: 然后把下载好的文件上 ...
- Spring boot集成RabbitMQ(山东数漫江湖)
RabbitMQ简介 RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统 MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过读写出 ...
随机推荐
- Integer和Long部分源码分析
Integer和Long的java中使用特别广泛,本人主要一下Integer.toString(int i)和Long.toString(long i)方法,其他方法都比较容易理解. Integer. ...
- 使用Python来写mock代码(桩代码)-其实很简单
1.Mock基本用法 使用Mock能创建你能访问(模拟)的属性和方法 指定类或者函数的返回值和断言方式 创建handle_mock_01.py文件 # 1. 导入mock模块 from unittes ...
- Ethical Hacking - GAINING ACCESS(17)
CLIENT SIDE ATTACKS - Backdooring exe' s Download an executable file first. VEIL - FRAMEWORK A backd ...
- Python Hacking Tools - Vulnerability Scanner
Security Header website: https://securityheaders.com/ Scan the target website: https://www.hackthiss ...
- STL源码剖析:关联式容器
AVL树 AVL树定义:红黑树是一颗二叉搜索树,特别的是一棵保持高度平衡的二叉搜索树 AVL树特点: 每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1 AVL树插入: 说明:新增节点的平衡因子 ...
- Eclipse开发Web项目连接MySQL时找不到驱动的解决办法
当我们使用Eclipse开发Web项目连接MySQL时后台报找不到驱动的错误,如下:解决办法: 1.这时我们首先要检查我们是否导入了连接MySQL数据库的jar包,如图,是否已经将jar包复制到项目下 ...
- 跟老刘学运维day03~新手必须掌握的Linux命令(3)
第2章 Linux命令 今天已经跟老刘学习运维第三天了,前两天对虚拟机和Linux系统的安装进行了深入的学习,今天开始命令的学习 系统状态检测命令 1.ifconfig 2.uname:查看系统内 ...
- expect使用技巧
1) 获取命令行参数,例如通过./abc.exp a1 a2执行expect脚本 set 变量名1 [lindex $argv 0] 获取第1个参数a1 set 变量名2 [lindex $argv ...
- Java Script 数组
数组:有许多变量的集合,它们的名称和数据类型都是一致的. 定义 操作(添加修改) Var arr=new Array(): Var arr=[ ]; //定义 Var arr1=[ 1,2,3, ...
- Fortify Audit Workbench 笔记 Race Condition: Singleton Member Field 竞争条件:单例的成员字段
Race Condition: Singleton Member Field 竞争条件:单例的成员字段 Abstract Servlet 成员字段可能允许一个用户查看其他用户的数据. Explanat ...