RabbitMQ是做什么的?

RabbitMQ可以类比现实生活中的邮政服务。

现实中邮件服务处理的是邮件,发件人写好信件投入邮箱,邮递员收取信件存入邮局,邮局根据信件地址,分配邮递员投递信件到指定地点。

RabbitMQ与邮政服务的主要区别是RabbitMQ处理的是消息(二进制数据块), 即消息的接收、存储、分发。

RabbitMQ中的主要概念

消息生产者(producer)

发送消息的程序

消息消费者(Consumer)

等待接收消息的程序

消息队列

RabbitMQ中的消息队列,就相当于邮政服务中的邮箱,所有通过RabbitMQ和你的应用程序发送接收的消息都存储在消息队列中,它是一个巨大的消息缓存,它的大小仅受服务器内存和硬盘空间的限制。

多个消息生产者可以通过同一个消息队列发送消息,多个消息消费者也可以通过同一个消息队列接收消息。

消息的生产者、消费者、消息队列不需要一定放置在同一个服务器中,现实中的大部分应用场景也不会允许他们放置在同一服务器中

第一个Hello World程序

这里我们创建2个控制台程序,一个负责发送简单的 Hello World消息,一个负责输出接收到的消息,并在控制台打印。

流程图如下,P为生产者,C为消费者,中间的红色块是消息队列

创建程序

使用.NET Core的命令行工具,创建2个控制台程序,一个命名为Send, 另外一个命名为Receive。

dotnet new console –name Send

dotnet new console –name Receive

安装RabbitMQ客户端程序集

使用.NET Core的命令行工具,分别为2个控制台程序添加RabbitMQ客户端程序集

dotnet add package RabbitMQ.Client

dotnet restore

编写消息发送程序

首先引入一些命名空间

using System;

using RabbitMQ.Client;

using System.Text;

然后在修改Main方法添加如下代码

var factory = new ConnectionFactory() { HostName = "localhost" };

        using (var connection = factory.CreateConnection())

        {

            using (var channel = connection.CreateModel())

            {

               

            }

        }

connection对象抽象出了一个Socket连接,并负责RabbitMQ所使用的协议版本的验证和协商。

这里连接的是本地的RabbitMQ实例,所以使用的localhost作为主机名,如果需要连接其他服务器的RabbitMQ实例,只需要将主机名变更为对应服务器的ip地址即可。

然后我们需要创建一个channel对象,大部分的消息处理有关的api都是在channel对象中。

接下来,为了发送消息,我们需要创建一个消息队列,然后向这个消息队列中发布消息。

using System;

using RabbitMQ.Client;

using System.Text;

 

class Send

{

    public static void Main()

    {

        var factory = new ConnectionFactory() { HostName = "localhost" };

        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(" [x] Sent {0}", message);

        }

 

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

        Console.ReadLine();

    }

}

Channel对象的QueueDeclare方法是用来声明一个消息队列的,这个方法是等幂的,即只要当该消息队列不存在的时候才创建他,如果已经存在,就直接返回之前创建的对象。

RabbitMQ中传递的消息是二进制数据,所以需要将传递的文本转换成二进制数据。

这样消息发送程序就完成了。

编写接收消息程序

前面我们做的发送程序运行一次只发送一条消息,与发送程序不同,接收消息程序需要监听接收到的所有消息,并打印。

首先我们引入需要使用的命名空间

using RabbitMQ.Client;

using RabbitMQ.Client.Events;

using System;

using System.Text;

初始的设置代码和发送程序一样

public static void Main()

    {

        var factory = new ConnectionFactory() { HostName = "localhost" };

        using (var connection = factory.CreateConnection())

        {

            using (var channel = connection.CreateModel())

            {

                channel.QueueDeclare(queue: "hello",

                                     durable: false,

                                     exclusive: false,

                                     autoDelete: false,

                                     arguments: null);

               

            }

        }

    }

这里还要重复声明一次消息队列的原因是,你不能保证在消息接收程序启动时,消息队列一定存在(即消息接收程序的启动早于发送消息程序)。

由于消息的推送是异步的,所以这里我们需要使用事件来捕捉消息,并打印在控制台

var factory = new ConnectionFactory() { HostName = "localhost" };

        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(" [x] Received {0}", message);

            };

            channel.BasicConsume(queue: "hello",

                                 autoAck: true,

                                 consumer: consumer);

 

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

            Console.ReadLine();

        }

运行程序

在消息发送程序和消息接收程序目录下,使用.NET Core命令行工具启动2个项目

dotnet run

RabbitMQ学习笔记(一) Hello World的更多相关文章

  1. RabbitMQ学习笔记(五) Topic

    更多的问题 Direct Exchange帮助我们解决了分类发布与订阅消息的问题,但是Direct Exchange的问题是,它所使用的routingKey是一个简单字符串,这决定了它只能按照一个条件 ...

  2. RabbitMQ学习笔记1-hello world

    安装过程略过,一搜一大把. rabbitmq管理控制台:http://localhost:15672/   默认账户:guest/guest RabbitMQ默认监听端口:5672 JAVA API地 ...

  3. (转) Rabbitmq学习笔记

    详见原文: http://blog.csdn.net/shatty/article/details/9529463 Rabbitmq学习笔记

  4. 官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

    在第二节我们进行了RabbitMQ的安装,现在我们就RabbitMQ进行集群的搭建进行学习,参考官网地址是:http://www.rabbitmq.com/clustering.html 首先我们来看 ...

  5. 官网英文版学习——RabbitMQ学习笔记(一)认识RabbitMQ

    鉴于目前中文的RabbitMQ教程很缺,本博主虽然买了一本rabbitMQ的书,遗憾的是该书的代码用的不是java语言,看起来也有些不爽,且网友们不同人学习所写不同,本博主看的有些地方不太理想,为此本 ...

  6. RabbitMQ学习笔记五:RabbitMQ之优先级消息队列

    RabbitMQ优先级队列注意点: 1.只有当消费者不足,不能及时进行消费的情况下,优先级队列才会生效 2.RabbitMQ3.5以后才支持优先级队列 代码在博客:RabbitMQ学习笔记三:Java ...

  7. RabbitMQ学习笔记(六) RPC

    什么RPC? 这一段是从度娘摘抄的. RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的 ...

  8. 官网英文版学习——RabbitMQ学习笔记(八)Remote procedure call (RPC)

    在第四篇学习笔记中,我们学习了如何使用工作队列在多个工作者之间分配耗时的任务.   但是,如果我们需要在远程计算机上运行一个函数并等待结果呢?这是另一回事.这种模式通常称为远程过程调用或RPC.   ...

  9. 官网英文版学习——RabbitMQ学习笔记(二)RabbitMQ安装

    一.安装RabbitMQ的依赖Erlang 要进行RabbitMQ学习,首先需要进行RabbitMQ服务的安装,安装我们可以根据官网指导进行http://www.rabbitmq.com/downlo ...

  10. RabbitMQ学习笔记一

    前 言 -解决问题  一.RabbitMQ安装  1.安装erlang 环境 a.下载erlang 版本,注意这里需要和安装的rabbitMq版本相配对,rabbitMQ官方网站上可以查到:https ...

随机推荐

  1. Codeforces 939E Maximize! (三分 || 尺取)

    <题目链接> 题目大意:给定一段序列,每次进行两次操作,输入1 x代表插入x元素(x元素一定大于等于之前的所有元素),或者输入2,表示输出这个序列的任意子集$s$,使得$max(s)-me ...

  2. 多标签caffe重新编译

    说明: Caffe自带的图像转LMDB接口只支持单label,对于多label的任务,可以使用HDF5的格式,也可以通过修改caffe代码来实现.本篇文章介绍怎么通过修改DataLayer来实现带Mu ...

  3. C#的排序Sort和OrderBy扩展方法

    可以实现一个IComparable接口的CompareTo方法,或者是给予List的Sort扩展方法,传入委托实现,举个例子: list.Sort((a, b) => { var o = a.s ...

  4. sqlzoo:6

    第一個例子列出球員姓氏為'Bender'的入球數據. * 表示列出表格的全部欄位,簡化了寫matchid, teamid, player, gtime語句. 修改此SQL以列出 賽事編號matchid ...

  5. springmvc是如何工作的

    上图便是springmvc的工作流程,看着条条框框的,其实说的直白一点,springmvc就是负责处理用户的需求(request/url),它的负责人(核心组件)就是前端控制器(DispatcherS ...

  6. 图解Raft之日志复制

    日志复制可以说是Raft集群的核心之一,保证了Raft数据的一致性,下面通过几张图片介绍Raft集群中日志复制的逻辑与流程: 在一个Raft集群中只有Leader节点能够接受客户端的请求,由Leade ...

  7. Luogu P1894 [USACO4.2]The Perfect Stall

    传送门 是道绿题???二分图(网络流)不应该是蓝打底??? 这题浏览一遍就知道是二分图(网络流)算法喽,二分图代码太短,不想写(←这人???),所以就拿网络流练练手. 设源点S=0,汇点T=n+m+1 ...

  8. 在 Ubuntu 中使用 Visual Studio Code

    前言 我一直在 Linux 桌面系统下的探索寻找各种界面美观.使用舒适的软件工具.对于Linux下的开发人员来讲,这几年最大的福利就是 MicroSoft 推出的 Visual Studio Code ...

  9. JQuery实现 图片上传

    用到的文件,我都已经打包好了,自行下载: https://files.cnblogs.com/files/lguow/lib.rar 核心代码如下: <input type="hidd ...

  10. [Swift]LeetCode148. 排序链表 | Sort List

    Sort a linked list in O(n log n) time using constant space complexity. Example 1: Input: 4->2-> ...