RabbitMQ 简介

本文对应 RabbitMQ 官方教程的第一个例子——Hello World,用简单例子来初步了解 RabbitMQ 是什么。

简介

RabbitMQ 官方教程

一个类比

请看官方教程中的一个类比:

RabbitMQ 是一个消息代理: 它接受并转发消息。
你可以把它看作是一个邮局: 当你把你想要发布的邮件放在邮箱里时, 你可以肯定, 邮递员最终会把邮件交给你的收件人。
在这个比喻中, RabbitMQ 是一个邮筒、一个邮局和一个邮递员

类比思维,可以让我们用来作为了解一样事物的切入点,但类比或多或少有点失真。
这里特别强调的时候,现实邮件是从一个人送到另外一个人手上的,
但 RabbitMQ 却有各种不同的场景(接下来要各章节要将的内容),所以思维上不要被官方的类比固化了。

一些术语

Producer(生产者):发送消息的程序,我们称之为生产者。
生产者

Queue(队列):队列是在 RabbitMQ 中的邮箱的名称。
虽然消息流经 RabbitMQ 和您的应用程序,但它们只能存储在队列中。
队列只受主机的内存和磁盘限制的约束,它本质上是一个大的消息缓冲区。
许多生产者可以发送到一个队列的消息,并且许多消费者可以尝试从一个队列接收数据。
队列

Consumer(消费者):消费和接收有着相似的含义,所以消费者就是指那些主要负责等待接收消息的程序。

值得注意的是,producer(生产者), consumer(消费者),和 broker(中间件,这里指 RabbitMQ),不是一定要部署在同一台主机上,
事实上,在大多数应用当中都不会部署在同一台机器上,
但一个应用程序既可以是生产者,也可以是消费者。

“Hello World”

在本教程的这一部分中,我们将用 C# 编写两个程序;
生产者发送单个消息,消费者接收消息并将其打印出来的。
我们将掩盖 .NET 客户端 API 中的一些细节,专注于这个非常简单的事情,只是为了快速开始。
消息将会传递的 “Hello World”。

在下图中,“P” 是我们的生产者,“C” 是我们的消费者,中间的框是一个队列——RabbitMQ 代表消费者保留的消息缓冲区。
RabbitMQ 简单模型

发送

发送消息到队列中

We’ll call our message publisher(sender) and our message consumer(receiver)
这里有整了几个术语出来:
Producer(生产者) = publisher(发布者) = sender(发送者)
Consumer(消费者) = receiver(接收者)

发布者将连接到 RabbitMQ,发送单个消息,然后退出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using System;
using System.Text;
using RabbitMQ.Client; // 请自行用 NuGet 添加依赖

namespace MqProducer
{
class Program
{
// 这是 生产者(发布者,发送者) 的示例代码
static void Main(string[] args)
{
var factory = new ConnectionFactory();
factory.HostName = "192.168.86.130";// 这是我的 RabbitMQ 服务器地址
factory.Port = 5672;
factory.UserName = "admin";//用户名
factory.Password = "admin";//密码

using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
// 声明一个队列,声明队列是幂等的 - 只有在它不存在的情况下才会创建它。
channel.QueueDeclare(queue: "hello",
durable: false, // 猜测各个参数的含义
exclusive: false,
autoDelete: false,
arguments: null);

string message = "Hello World!";
var body = Encoding.UTF8.GetBytes(message);

// 发送消息
channel.BasicPublish(exchange: "",
routingKey: "hello",
basicProperties: null,
body: body);

Console.WriteLine(" [生产者] 发送消息: {0}", message);
}

Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
}

}
}

接收

至于消费者,它会监听来自 RabbitMQ 的消息。
因此,与发布单个消息的发布者不同,我们将使消费者持续运行以侦听消息并将其打印出来。

从队列中接收到消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using System;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

namespace MqConsumer
{
class Program
{
// 这是 消费者(接收者) 的示例代码
static void Main(string[] args)
{
var factory = new ConnectionFactory();
factory.HostName = "192.168.86.130";// 这是我的 RabbitMQ 服务器地址
factory.Port = 5672;
factory.UserName = "admin";//用户名
factory.Password = "admin";//密码

using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
// 声明一个队列,声明队列是幂等的 - 只有在它不存在的情况下才会创建它。
channel.QueueDeclare(queue: "hello",
durable: false,
exclusive: false,
autoDelete: false,
arguments: null);

var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(" [消费者] 接收到消息: {0}", message);
};

// 指明监听哪个队列
channel.BasicConsume(queue: "hello",
autoAck: true,
consumer: consumer);

Console.WriteLine("我的心在等待,永远在等待...");
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
}
}
}
}

Tips:
队列 hello,由谁创建,与谁的关系密切,由谁回收?

运行看看

先运行 消费者 端

1
MqConsumer> dotnet run

或者

1
\MqConsumer\bin\Debug\netcoreapp2.1> dotnet MqConsumer.dll

这个时候登录 RabbitMQ 的管理界面,
http://192.168.86.130:15672 (192.168.86.130 是我服务器的地址,请自行替换)

看看 queues 中有什么。

再运行 生产者 端

1
\MqProducer> dotnet run

或者

1
\MqProducer\bin\Debug\netcoreapp2.1> dotnet MqProducer.dll

另外,观察一下:先关闭 消费者 端,再运行一次 生产者 端,再运行 消费者 端。

结束语

以下是官方的免责声明:

生产[非]适用性免责声明
请记住,这个和其他教程都是教程。
他们一次展示一个新概念,可能会故意过度简化某些事情而忽略其他事物。
例如,为了简洁起见,在很大程度上省略了诸如连接管理,错误处理,连接恢复,并发和度量收集之类的主题。
这种简化的代码不应用于生产环境。

要使用好 RabbitMQ,还有很多内容需要学习,所以继续下一章的 Work Queues(工作队列)

觉得文章对您有帮助,请我喝瓶肥宅快乐水可好 (๑•̀ㅂ•́)و✧
  • 本文作者: 阿彬~
  • 本文链接: https://iweixubin.github.io/posts/rabbitmq/hello-world/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 免责声明:本媒体部分图片,版权归原作者所有。因条件限制,无法找到来源和作者未进行标注。
         如果侵犯到您的权益,请与我联系删除