本章学习目标

  • 理解AMQP模型中的核心概念:Connection, Channel, Producer, Consumer, Queue。

  • 创建一个.NET项目并添加RabbitMQ客户端库。

  • 使用C#编写代码发送一条消息("Hello World")。

  • 使用C#编写代码接收并处理这条消息。


一、理论部分

1. AMQP 0-9-1 核心模型简介

在编写代码前,我们需要理解几个核心概念,它们构成了RabbitMQ一切功能的基础:

  • 生产者 (Producer):发送消息的应用程序。

  • 消费者 (Consumer):接收消息的应用程序。

  • 队列 (Queue):一个类似于邮箱的存储结构,位于RabbitMQ内部,用于存储消息。多个生产者可以向同一个队列发送消息,多个消费者也可以从同一个队列接收消息。消息只能存储在队列中。

  • 连接 (Connection):一个TCP连接,应用程序通过它与RabbitMQ服务器建立网络连接。创建连接的开销较大。

  • 通道 (Channel):建立在连接之上的虚拟连接。几乎所有的操作都在通道中进行。使用通道的原因是为了避免频繁创建和销毁TCP连接带来的巨大开销。一个连接可以包含多个通道。

简单工作流:Producer -> (Connection -> Channel) -> Queue -> (Channel -> Connection) -> Consumer

2. RabbitMQ.Client 库

这是RabbitMQ官方提供的.NET客户端库,它实现了AMQP协议,是我们与RabbitMQ服务器交互的桥梁。我们将通过NuGet包管理器来安装它。


二、实操部分:创建"Hello World"

我们将创建两个控制台应用程序:一个生产者(Send)和一个消费者(Receive)。

第1步:创建项目并添加NuGet包

  1. 打开IDE(如Visual Studio或VS Code),创建一个新的解决方案(Solution)。

  2. 在该解决方案中,创建两个新的控制台应用程序项目,分别命名为 Send 和 Receive

  3. 为两个项目添加 RabbitMQ.Client NuGet包。

    • Visual Studio:右键点击项目 -> "Manage NuGet Packages..." -> 浏览 -> 搜索 RabbitMQ.Client -> 安装。

    • .NET CLI:

      cd /path/to/Send
      dotnet add package RabbitMQ.Client cd /path/to/Receive
      dotnet add package RabbitMQ.Client

第2步:编写生产者(Send.cs)

将 Send 项目中的 Program.cs 替换为以下代码。请务必将 hostNameuserName 和 password 替换为在上1章中设置的值(如果按教程做,应该是 localhostmyusermypassword)。

using System.Text;
using RabbitMQ.Client; // 1. 创建连接工厂(ConnectionFactory)并设置连接参数
var factory = new ConnectionFactory()
{
HostName = "localhost", // RabbitMQ服务器地址
UserName = "myuser", // 用户名
Password = "mypassword" // 密码
}; // 2. 使用工厂创建一个连接(Connection)和一个通道(Channel)
// 'using' 语句确保在代码块结束时,连接和通道会被正确关闭和释放,这是很重要的。
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
// 3. 声明一个队列。如果队列不存在,则创建它。
// 参数说明:
// queue: "hello" - 队列的名称
// durable: false - 队列是否持久化(服务器重启后是否存在)
// exclusive: false - 是否为当前连接的专用队列(其他连接不能访问)
// autoDelete: false - 当最后一个消费者断开后,队列是否自动删除
channel.QueueDeclare(queue: "hello",
durable: false,
exclusive: false,
autoDelete: false,
arguments: null); // 4. 准备要发送的消息
string message = "Hello World!";
var body = Encoding.UTF8.GetBytes(message); // 将消息转换为字节数组 // 5. 发布消息到队列
// 参数说明:
// exchange: "" - 使用默认的(无名)交换机
// routingKey: "hello" - 路由键,对于默认交换机,它指定了消息要发送到的队列名称
// basicProperties: null - 消息属性(如持久化)
// body: body - 消息体
channel.BasicPublish(exchange: "",
routingKey: "hello",
basicProperties: null,
body: body); Console.WriteLine($" [x] Sent {message}");
} Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();

代码解析:

  • 我们首先创建了一个连接工厂,并配置了连接到我们本地RabbitMQ服务器所需的参数。

  • 然后,我们建立了连接和通道。这是与RabbitMQ交互的标准方式。

  • QueueDeclare 是幂等的——它只会在队列不存在时创建它。

  • 默认交换机("")是一个直连交换机(Direct Exchange),它会把消息路由到 routingKey 完全匹配的队列中。所以这里 routingKey: "hello" 意味着消息会被投递到名为 hello 的队列。

第3步:运行生产者并查看管理后台

  1. 运行 Send 项目(在Visual Studio中按F5,或使用CLI命令 dotnet run)。

  2. 会在控制台看到 [x] Sent Hello World!

  3. 现在,打开RabbitMQ管理后台 (http://localhost:15672),登录后点击 Queues 标签页。应该能看到一个名为 hello 的队列,并且它下面有 1 条消息正准备被消费("Ready"状态)!

第4步:编写消费者(Receive.cs)

现在我们来编写消费者程序,从 hello 队列中取出消息。

将 Receive 项目中的 Program.cs 替换为以下代码:

using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events; // 同生产者一样,创建连接和通道
var factory = new ConnectionFactory() { HostName = "localhost", UserName = "myuser", Password = "mypassword" };
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
// 声明队列。这一步也是必需的,以防我们先启动消费者,而队列还不存在。
channel.QueueDeclare(queue: "hello",
durable: false,
exclusive: false,
autoDelete: false,
arguments: null); // 创建一个事件消费者(EventingBasicConsumer)对象,并关联到我们的通道
var consumer = new EventingBasicConsumer(channel); // 当消费者收到消息时,触发这个事件
consumer.Received += (model, ea) =>
{
// 消息体是字节数组,我们需要将其转换回字符串
var body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
Console.WriteLine($" [x] Received {message}");
}; // 开始消费队列中的消息
// 参数说明:
// queue: "hello" - 要消费的队列名称
// autoAck: true - 自动确认模式。如果为true,消息一旦被送达,RabbitMQ会立即将其从队列中标记为删除。
// consumer: consumer - 我们上面定义的消费者对象
channel.BasicConsume(queue: "hello",
autoAck: true,
consumer: consumer); Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine(); // 保持程序运行,持续监听消息
}

代码解析:

  • 前面的连接、通道、队列声明步骤与生产者完全一致,这确保了所需的队列存在。

  • 我们创建了一个 EventingBasicConsumer 对象,并为它的 Received 事件订阅了一个处理方法。每当有消息到达时,这个匿名方法就会被调用。

  • BasicConsume 方法启动消费过程。它将我们的消费者注册到指定的队列。

  • autoAck: true 表示自动确认模式。这意味着消费者一收到消息,RabbitMQ就认为它已成功处理并立即从队列中删除该消息。这是一种简单的模式,但如果消费者在处理消息过程中崩溃,消息就会丢失。我们将在下一章学习更可靠的手动确认模式。

第5步:运行消费者

  1. 运行 Receive 项目。

  2. 会立刻在控制台看到 [x] Received Hello World!。消费者程序取走了我们之前发送的消息并打印了出来。

  3. 再次查看管理后台的 Queues 页面,会发现 hello 队列中的消息数又变回了 0。

尝试一下:

  1. 先运行 Receive 程序,让它保持运行并监听消息。

  2. 然后再运行 Send 程序多次。

  3. 观察 Receive 的控制台,它会实时地打印出每一条新收到的消息。


总结

我们已经成功实现了一个RabbitMQ应用程序。在本文中,我们:

  1. 创建了.NET项目并引入了 RabbitMQ.Client 库。

  2. 理解了AMQP模型中的 ConnectionChannelQueueProducer 和 Consumer 等核心概念。

  3. 编写了生产者代码,成功向名为 hello 的队列发送了一条消息。

  4. 编写了消费者代码,成功从队列中取出了消息并进行处理。

  5. 使用了管理后台来验证消息的流动。

这是一个最简单的模型,生产者和消费者直接与队列打交道。在下一章,我们将学习如何实现工作队列(Work Queue)与消息确认(Ack),让多个消费者共同处理任务,这将使我们的应用变得更加实用和强大。

【RabbitMQ】核心模型简介,以及消息的生产与消费的更多相关文章

  1. SpringBoot 整合 RabbitMQ(包含三种消息确认机制以及消费端限流)

    目录 说明 生产端 消费端 说明 本文 SpringBoot 与 RabbitMQ 进行整合的时候,包含了三种消息的确认模式,如果查询详细的确认模式设置,请阅读:RabbitMQ的三种消息确认模式 同 ...

  2. RabbitMQ~一些术语和最消息的生产

    学习一种技术需要先了解它,而想要学好一种技术,需要更多的了解它的组成,原理和实现机制! RabbitMQ安装介绍 RabbitMQ是由erlang语言开发的,所以必须先有安装erlang,类似java ...

  3. RocketMQ系列(三)消息的生产与消费

    前面的章节,我们已经把RocketMQ的环境搭建起来了,是一个两主两从的异步集群.接下来,我们就看看怎么去使用RocketMQ,在使用之前,先要在NameServer中创建Topic,我们知道Rock ...

  4. ActiveMQ使用线程池实现消息的生产与消费

    jar文件:spring3.1jar,以及 项目src路径下文件:config.properties 读取config.properties文件JAVA类: package com.lejob.lej ...

  5. RabbitMQ常用的几种消息模型

    第一种模型(HelloWorld) 上图来自官方文档 P代表生产者用来生产消息,发送给消费者C,中间的共色部分代表消息队列,用来缓存消息. 首先导入依赖 <dependency> < ...

  6. RabbitMQ,RocketMQ,Kafka 消息模型对比分析

    消息模型 消息队列的演进 消息队列模型 发布订阅模型 RabbitMQ的消息模型 交换器的类型 direct topic fanout headers Kafka的消息模型 RocketMQ的消息模型 ...

  7. 消息中间件——RabbitMQ(三)理解RabbitMQ核心概念和AMQP协议!

    前言 本章学习,我们可以了解到以下知识点: 互联网大厂为什么选择RabbitMQ? RabbiMQ的高性能之道是如何做到的? 什么是AMQP高级协议? AMQP核心概念是什么? RabbitMQ整体架 ...

  8. 1.RabbitMQ工作模型与基本原理

        1.了解 MQ 的本质和 RabbitMQ 的特性: 2.掌握 RabbitMQ 的 Java API 编程和 Spring 集成 RabbitMQ 1. MQ 了解 1.1. 消息队列简介 ...

  9. 【SpringBoot MQ 系列】RabbitMq 核心知识点小结

    [MQ 系列]RabbitMq 核心知识点小结 以下内容,部分取材于官方教程,部分来源网络博主的分享,如有兴趣了解更多详细的知识点,可以在本文最后的文章列表中获取原地址 RabbitMQ 是一个基于 ...

  10. 认识RabbitMQ交换机模型

    前言 RabbitMQ是消息队列中间件(Message Queue Middleware)中一种,工作虽然有用到,但是却没有形成很好的整体包括,主要是一些基础概念的认识,这里通过阅读<Rabbi ...

随机推荐

  1. java有关正则表达式的工具方法集合1

    1.获取某字符串中汉字的个数 1 ... 2 private int getChineseCount(String text) { 3 String Reg = "^[\u4e00-\u9f ...

  2. react发布一个组件库 系列篇(二)

    前言 在上篇说到,不是特殊情况,我们尽量还是把源码打包编译成es5之后再发布到npm,这样用户使用的时候就很方便. 接下来我们就还拿上章的代码,使用rollup+babel编译.打包后再发版,来举个例 ...

  3. 多个pdf和图片、word实现预览和下载

    效果 代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  4. 模拟退火 python 实现

    简介 一直以为是一个高深的算法,好像据说在量子计算机中可以应用.发现原理并不难 参考链接 https://blog.csdn.net/google19890102/article/details/45 ...

  5. Applied Statistics - 应用统计学习 - numpy array交换两行 ? How to Swap Two Rows in a NumPy Array (With Example)

    https://www.statology.org/qualitative-vs-quantitative-variables/ https://www.statology.org/numpy-swa ...

  6. js入门基础语法

    js入门基础语法 什么是javaScript 概述 javaScript是世界上最流行的一门脚本语言 javaScript是一门很随意的语言 有句话叫做如果可以重新来过我就只愿意学javaScript ...

  7. tauri学习(6)-系统托盘systemTray

    接上节继续,研究下系统托盘. 一.tauri.conf.json配置启用系统托盘 二.Rust中添加托盘 运行效果: 但是只有一个托盘图标,点了啥反应都没有. 三.给托盘加菜单 效果: 接下来,给托盘 ...

  8. Argo CD持续交付工具部署

    介绍 Argo CD 是一款适用于 Kubernetes 的声明式 GitOps 持续交付工具. 架构 Argo CD 是作为一个 Kubernetes 控制器来实现的,它能持续监控运行中的应用程序, ...

  9. Apereo CAS 4.1 反序列化命令执行漏洞 (复现)

    此漏洞需要用到工具Apereo-CAS-Attack,工具地址:https://github.com/vulhub/Apereo-CAS-Attack 还需要下载结合https://github.co ...

  10. zuul 网关超时优化

    1. 概述 前段时间,线上的服务不知道为啥,突然全部的服务都超时,所有的请求经过网关都超时,后来进行链路追踪排查,发现有一个服务链接 RDS 数据库,一个查询花费了 20S 的查询时间,导致后续调用该 ...