3

gitBook https://joursion.gitbooks.io/...

Title: RabbitMQ tutorials ---- 'Hello World' (Javascript)


介绍

RabbitMQ 是一个消息代理,其主要思想比较简单。允许接收和转发消息。你可以把RabbitMQ想成是一个邮局,当你发一份邮件到邮箱,你相当确定邮递员最终会把这封信送到你的收件人那边。
使用这个比喻,RabbitMQ可以是一个邮箱,或一个邮局,或一个邮递员。
其与邮局主要的不同是实际上RabbitMQ并不处理内容,而是接收,存储然后转发二进制数据--消息(message)

在RabbitMQ的消息传递上,我们用一些术语来解释:

  • 生产(Producing) 意味着只做发送的事情。一个发送消息(message)的程序可以作为一个生产者(producer).图如下,代号‘P’

p

  • 队列(queue)是一个邮箱的名字,存在在 RabbitMQ中。尽管消息(messages)是在RabbitMQ和你的应用中传递,但是它们只能被存到一个队列中。这个队列没有任何限制,可以存储你想要的任何多的消息,实际上,它就是一个无限的Buffer,大量生产者可以把消息发送到一个
    队列中,消费者们可以尝试从一个队列中去接收数据。一个队列可以画成下图所示:上方是它的名字

queue

  • 消费(Consuming)和接收的意思类似。一个等待接收消息的程序是一个消费者(Consumer)。如下图所示,代号“C”:

c

"Hello World"

(使用amqp.node[1] 客户端)

在这个部分的引导中,我们会写两个Javascript小程序,一个生产者用来发送一条消息,一个消费者来接收消息并打印出来。考虑到这只是一个起步入门的小代码,消息传送一个‘hello world’
在途中,“P”是我们的生产者,“C”是我们的消费者,在中间的盒子是一个队列(queue),一个RabiitMQ用来给消费者代理的buffer.

amqp.node 客户端库
RabbitMQ 支持多种协议,在引导中,使用AMQP 0-9-1,它是一个开源的,通用的消息传递协议。支持很多不同语言的RabbitMQ的客户端库,在这里我们使用amqp.node (Javascript)

在一开始,我们使用npm 来安装这个库
$ npm install amqplib

现在我们已经安装了amqp.node了,我们可以写一些代码了

  • 发送(Sending):

sending

我们把消息发送者的文件取名send.js,同理,消息接收者的文件为receive.js。发送者会先连接到RabbitMQ,发送一条消息,然后退出。

send.js中,我们先导入库

#!/usr/bin/env node

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

再连接到RabbitMQ服务器
amqp.connect('amqp://localhst), function(err, conn) {} )

接着我们创建一个通道(channel),之后大部分的API会使用这个通道

amqp.connect('amqp://localhost', function(err, conn) {
    conn.createChannel(function(err, ch) {});
});

去发送的时候,我们必需声明一个队列(queue),然后把消息发布到这个队列中

amqp.connect('amqp://localhost', function(err, conn) {
    conn.createChannel(function(err, ch) {
        var q = 'hello';

        ch.assertQueue(q, {durable: false});  
        // Note: on Node 6 Buffer.from(msg) should be used
        ch.sendToQueue(q, new Buffer('Hello World!'));
        console.log(" [x] Sent 'Hello World!'");
  });
});

声明一个队列是幂等的[2] -- 只有在不存在的时候才会被创建。消息(message)的内容是一个位数组,所以你可以使用你喜欢的编码。
最后,我们要关闭这个连接并且退出

setTimeout(function() { conn.close(); process.exit(0) }, 500);

  • 接收(Receiving)
    以上就是发送的代码。我们的接收者是从RabbitMQ接收推送消息的,所以不同与发送者只需要发布一条简单的消息,我们需要保持程序持续运行,去监听消息并打印出来

receive

receive.js中,require同理

#!/usr/bin/env node

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

基础设置和send.js一致,先创建连接和通道,然后再声明一个我们要去消费的队列(queue)。注意:这里的queue是要和之前sendToQueue的名称一致。

amqp.connect('amqp://localhost', function(err, conn) {
    conn.createChannel(function(err, ch) {
        var q = 'hello'; //和之前的要一致,

        ch.assertQueue(q, {durable: false});
    });
});

注意:我们在这里也同样需要声明queue,因为我们可能先启动接收(receiver)再启动发送(sender),我们要保证当我们去从队列中取消息的时候,这个队列是存在的。

我们将会告诉服务器,我们要从这个队列取消息。由于推送给我们消息是异步的,我们需要写一个回调函数(callback),当RabbitMQ给消费者推送消息的时候执行。
这就是Channel.consume所作的

console.log(" [*] Waiting for messages in %s. To exit press CTRL+C", q);
ch.consume(q, 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(err, conn) {
  conn.createChannel(function(err, ch) {
    var q = 'hello';

    ch.assertQueue(q, {durable: false});
    console.log(" [*] Waiting for messages in %s. To exit press CTRL+C", q);
    ch.consume(q, function(msg) {
      console.log(" [x] Received %s", msg.content.toString());
    }, {noAck: true});
  });
});

整合(Putting it all together)

现在我们可以运行我们的这两个脚本了,在终端,我们去跑这两个脚本

sender:

$ ./sender.js

receive:

$ ./receive.js

reciever 中会打印一条从RabbitMQ中获取到的消息,并会持续运行(使用 ctrl+c 停止运行),等待新的消息推送。所以,你可以在其他终端再跑一次sender。
如果你想查看队列中的内容,可以使用rabbitmqctl list_queues

Hello World

下一节,将会讲到去搭建一个简单的工作队列


[1]. amqplib API

[2]. 在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。


小结: 消息队列从字面上就是一个管理消息的队列,存在消费者和生产者,缓存队列,他们可以订阅同一个queue。

翻译:Joursion

日期 :2016/12/21

另: 因为想入门RabbitMQ, 第一次想着翻译,第一次...然后... 希望多多提出不足。 Thanks~


Joursion
36 声望2 粉丝