RabbitQM 处理和管理消息队列的中间人(broker)。可简单理解为邮局,你在程序中写好消息,指定好收件人,剩下的事件就是 RabbitMQ 的工作了,它会保证收件人正确收到邮件。

任何发送邮件的程序都是 Producer,消息队列可理解为邮筒,新件将堆积在此处。所有待处理的消息都以队列形式存储,总体上看来就是一个巨大的消息 buffer,至于存储量与设置的内存及硬件有关。任何应用都可以向队列添加消息,也可以多个消费者都在从队列中获取消息。

consumer 即是消息队列中消息的应用,其处于等待接收来自 RabbitMQ 发送来的消息。

消息生产者,消费者及 RabbitMQ 这个中间人三者不必同时存在于同一机器上,实际运用时也确实大部分不会部署在同一机器上,比如有专门的机器作为 RabbitMQ 实体,而应用程序会部署在其他的集群。应用程序可以是同时负责生产消息的,也同时是消费者。

来自官方文档中关于 RabbitMQ 消息列队的示意图

安装

通过官网提供的地址下载相应平台的程序进行安装,Mac 可通过 Homebrew 进行安装

$ brew update && brew install rabbitmq

启动

如果使用 Homebrew 安装,可通过 brew services start rabbitmq 命令来启动 RabbitMQ 服务。

$ brew services start rabbitmq
==> Successfully started `rabbitmq` (label: homebrew.mxcl.rabbitmq)

或直接运行 /usr/local/sbin/rabbitmq-server

启动后,会有一个可视化的管理后台,可通过 http://localhost:15672/ 访问,用户名密码皆为 guest

基于 Node.js 的 Hello World 示例

通过 amqp.node 展示 RabbitMQ 在 Node.js 中应用的一个示例。

RabbmitMQ 支持多种协议进行通信,amqp.node 使用的是 AMQP 0-9-1 这一开源协议,后者专门为处理消息而设计。作为客户端消费消息,使用的是 amqp.node client 模块,但 RabbitMQ 本身是支持多种客户端的。

初始化一个 Node,js 项目然后通过以下命令安装 amqp.node 模块:

$ mkdir rabbitmq-demo && yarn init -y
$ yarn add amqplib

发送消息

创建 send.js 文件,在其中编写发送消息的逻辑,它将连接到 RabbitMQ 发送消息然后退出。

首先建立到 RabbitMQ 服务的连接,

#!/usr/bin/env node

var amqp = require('amqplib/callback_api');

amqp.connect('amqp://localhost', function(error0, connection) {});

连接建立成功后,创建一个通道(channel),具体的发送将会在这个通道中进行。

amqp.connect('amqp://localhost', function(error0, connection) {
if (error0) {
throw error0;
}
connection.createChannel(function(error1, channel) {});
});

发送消息前,需要先声明一个队列,然后将消息发送到该队列:

amqp.connect('amqp://localhost', function(error0, connection) {
if (error0) {
throw error0;
}
connection.createChannel(function(error1, channel) {
if (error1) {
throw error1;
}
var queue = 'hello';
var msg = 'Hello world';
<span class="pl-smi">channel</span>.<span class="pl-en">assertQueue</span>(queue, {
durable<span class="pl-k">:</span> <span class="pl-c1">false</span>
}); <span class="pl-smi">channel</span>.<span class="pl-en">sendToQueue</span>(queue, <span class="pl-smi">Buffer</span>.<span class="pl-en">from</span>(msg));
<span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">"</span> [x] Sent %s<span class="pl-pds">"</span></span>, msg);

});

});

队列的创建是一个幂等操作,只该队列不存在的情况才会新建。

最后关闭连接并退出。

setTimeout(function() {
connection.close();
process.exit(0);
}, 500);
完整的 send.js
#!/usr/bin/env node

var amqp = require('amqplib/callback_api');

amqp.connect('amqp://localhost', function(error0, connection) {

if (error0) {

throw error0;

}

connection.createChannel(function(error1, channel) {

if (error1) {

throw error1;

}
    <span class="pl-k">var</span> queue <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>hello<span class="pl-pds">'</span></span>;
<span class="pl-k">var</span> msg <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>Hello World!<span class="pl-pds">'</span></span>; <span class="pl-smi">channel</span>.<span class="pl-en">assertQueue</span>(queue, {
durable<span class="pl-k">:</span> <span class="pl-c1">false</span>
});
<span class="pl-smi">channel</span>.<span class="pl-en">sendToQueue</span>(queue, <span class="pl-smi">Buffer</span>.<span class="pl-en">from</span>(msg)); <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">"</span> [x] Sent %s<span class="pl-pds">"</span></span>, msg);
});
<span class="pl-c1">setTimeout</span>(<span class="pl-k">function</span>() {
<span class="pl-smi">connection</span>.<span class="pl-c1">close</span>();
<span class="pl-c1">process</span>.<span class="pl-en">exit</span>(<span class="pl-c1">0</span>);
}, <span class="pl-c1">500</span>);

});

接收消息

下面开始编写消费者,消费者做的事情是监听来自 RabbitMQ 的消息并处理。

创建 receive.js,引入 amqp.node 模块,流程和发送者一样,也是先创建连接,然后创建通道,在通道中声明需要监听的队列:

#!/usr/bin/env node

var amqp = require('amqplib/callback_api');

amqp.connect('amqp://localhost', function(error0, connection) {

if (error0) {

throw error0;

}

connection.createChannel(function(error1, channel) {

if (error1) {

throw error1;

}

var queue = 'hello';
<span class="pl-smi">channel</span>.<span class="pl-en">assertQueue</span>(queue, {
durable<span class="pl-k">:</span> <span class="pl-c1">false</span>
});

});

});

这里的队列声明不会与发送者那边的冲突,因为上面提到过,队列只在不存在的情况下才会重新生成。这里再次声明可以保证监听前队列已经存在。并且实际场景下,消费者有可能是在发送者之前启动的。

然后添加监听的逻辑:

 console.log(" [*] Waiting for messages in %s. To exit press CTRL+C", queue);

channel.consume(queue, function(msg) {

console.log(" [x] Received %s", msg.content.toString());

}, {

noAck: true

});
完整的 receive.js
#!/usr/bin/env node

var amqp = require('amqplib/callback_api');

amqp.connect('amqp://localhost', function(error0, connection) {

if (error0) {

throw error0;

}

connection.createChannel(function(error1, channel) {

if (error1) {

throw error1;

}
    <span class="pl-k">var</span> queue <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>hello<span class="pl-pds">'</span></span>;

    <span class="pl-smi">channel</span>.<span class="pl-en">assertQueue</span>(queue, {
durable<span class="pl-k">:</span> <span class="pl-c1">false</span>
}); <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">"</span> [*] Waiting for messages in %s. To exit press CTRL+C<span class="pl-pds">"</span></span>, queue); <span class="pl-smi">channel</span>.<span class="pl-en">consume</span>(queue, <span class="pl-k">function</span>(<span class="pl-smi">msg</span>) {
<span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">"</span> [x] Received %s<span class="pl-pds">"</span></span>, <span class="pl-smi">msg</span>.<span class="pl-c1">content</span>.<span class="pl-c1">toString</span>());
}, {
noAck<span class="pl-k">:</span> <span class="pl-c1">true</span>
});
});

});

运行

分别在命令行启动上面两个程序,查看打印的信息。

$ node send.js
[x] Sent Hello World! $ node receive.js

[*] Waiting for messages in hello. To exit press CTRL+C

[x] Received Hello World!

另外,可通过 sudo rabbitmqctl list_queues 手动查看 RabbitMQ 中的消息。

$ /usr/local/sbin/rabbitmqctl list_queues
Timeout: 60.0 seconds ...
Listing queues for vhost / ...
name messages
hello 0

如果发现 rabbitmqctl 命令不可用,需要添加 /usr/local/sbin 到环境变量中,

export PATH=/usr/local/sbin:$PATH

其中 fish shell 通过添加如下命令到 fish 的配置文件即可:

set -gx PATH /usr/local/sbin $PATH

相关资源

RabbitMQ Node.js 示例的更多相关文章

  1. 第 1 章 Node.js 介绍

    本章内容包括: 什么是 Node.js 框架,为什么要用 Node.js 框架,使用 Node.js 框架能够解决什么问题,在哪些场合下应该考虑使用 Node.js 框架. 如何下载 Node.js ...

  2. node.js微信小程序配置消息推送

    在开发微信小程序时,有一个消息推送,它的解释是这样的. 消息推送具体的内容是下面的这个网址   https://developers.weixin.qq.com/miniprogram/dev/fra ...

  3. Node.js下的Hello World

    Node.js技术现在可谓是如火如荼,前后端都统一为Javascript的体验绝对是受到了很多人的青睐,我都后悔以前没抽时间好好学一学Javascript了. 首先,我来介绍一下Node.js.本人实 ...

  4. 在 Web 应用中创建 Node.js 应用程序

    本分步指南将通过 Azure Web 应用帮助您启动并运行示例 Node.JS 应用程序.除 Node.JS 外,Azure Web 应用还支持其他语言,如 PHP..NET.Node.JS.Pyth ...

  5. Node.js | 你的物联网系统,有个管家待认领

    很多时候,专业的事情都要交给专业的人来做,才会更放心. 例如买了套房,交房装修完毕,欢天喜地入住后,房子的日常养护和维护之类的事情,都由谁来负责呢? 物业呗~买了房子就自然需要房子所在小区提供的物业服 ...

  6. node.js express安装及示例网站搭建

    1.首先肯定是要安装Node.JS windows cmd依次输入如下命令: cd C:\Program Files\nodejs\ npm install -g expressnpm install ...

  7. rabbitmq, windows/linux, c/c++/node.js/golang/dotnet

    官网:http://www.rabbitmq.com/ zeromq 相当于 message backbone,而rabbitmq相当于message broker.有的应用系统中,二者并存. (1) ...

  8. Hyperledger fabric Client Node.js Hello World示例程序

    简介 Hyperledger fabric Client (HFC)提供了基于Node.js的应用接口来访问Hyperledger区块. 本文介绍了一个使用HFC访问IBM Bluemixr区块服务的 ...

  9. Node.js与MongoDB的基本连接示例

    Node.js与MongoDB的基本连接示例 前提 已经安装了node.js和MongoDB,本文使用的node.js是v0.12.0,MongoDB是3.0.0. 初始化数据 启动MongoDB服务 ...

随机推荐

  1. vue使用--vuex快速学习与使用

    什么是vuex? Vuex核心概念 Vuex安装与使用 1.安装 2.目录结构与vuex引入 3.store中变量的定义.管理.派生(getter) 4.vuex辅助函数的使用说明 Vuex刷新数据丢 ...

  2. css多余文本使用....代替

    1. 只显示单行文本,多余文本使用...代替 white-space: nowrap; overflow: hidden; text-overflow: ellipsis; 2. 显示多行文本,多余文 ...

  3. Java入门系列之集合LinkedList源码分析(九)

    前言 上一节我们手写实现了单链表和双链表,本节我们来看看源码是如何实现的并且对比手动实现有哪些可优化的地方. LinkedList源码分析 通过上一节我们对双链表原理的讲解,同时我们对照如下图也可知道 ...

  4. 痞子衡嵌入式:飞思卡尔i.MX RTyyyy系列MCU特性那些事(2)- RT1052DVL6性能实测(CoreMark)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RTyyyy系列MCU的性能. 在前面的文章 i.MXRTyyyy微控制器概览 里,痞子衡给大家简介过恩智浦半导体在2 ...

  5. NetCore的Docker部署

    NetCore的Docker部署 一.NetCore与Docker Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或 ...

  6. 《少年的你》票房被刷爆?让我用python分析一波它好看在哪里!

    最近少年的你刷爆票房,但是是真好看还是假好看,我们也不知道,所以让我们用python来分析一下~ 票房过12亿 两位主演粉丝加起来过亿 电影话题量过亿 豆瓣8.4分, 时光网8.4分, IMDB 7. ...

  7. 松软科技web课堂:JavaScript 注释

    JavaScript 注释用于解释 JavaScript 代码,增强其可读性. JavaScript 注释也可以用于在测试替代代码时阻止执行. 单行注释 单行注释以 // 开头. 任何位于 // 与行 ...

  8. Python Web(一)

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 一.Web框架 1.socket网络编程 架构:C/S 协议:TCP/UDP 传输层 2.Web应用 架构:B/S ...

  9. session --中间件

    session的简介 session是另一种记录客户状态的机制,与cookie不同的是 session数据保存在服务器中,而不是保存在客户端浏览器中 session的用途 session运行在服务器端 ...

  10. apk系统签名小技巧

    前言 对于经常和android系统打交道的攻城狮来说,给app打系统签名一定是日常操作啦.由于最近使用的比较多,特此总结一下,减少复制粘贴的操作,通过命令行来搞定. 简化前的操作 1.Android ...