前面声明本文都是RabbitMQ的官方指南翻译过来的,由于本人水平有限难免有翻译不当的地方,如发现不对的地方,请联系下我,好及时改正。好了,正文开始:

RabbitMQ 是一个消息代理。这主要的原理十分简单,就是通过接受和转发消息。你可以把它想象成邮局:当你将一个包裹送到邮局,你会相信邮递员先生最终会将邮件送到接件人手上。RabbitMQ就好比一个邮箱,邮局或邮递员。

邮局和RabbitMQ两种主要的不同之处在于,RabbitMQ不处理文件,而是接受,并存储和以二进制形式将消息转发。

RabbitMQ,在消息的传送过程中,我们使用一些标准称呼。

生产过程就像发送过程,发送消息的程序就是一个生产者,我们使用“P”来描述它。

队列是好比邮筒的称呼,它位于RabbitMQ内部,虽然消息流通过RabbitMQ和你的应用程序,但是它们仅仅存储在队列中。一个队列没有范围 限制,你可以想存储多少就存储多少,本质上来说它是无限大的缓存。多个生产者可以通过一个队列发送消息,同样多个消费者也可以通同一个消息队列中接收消 息。队列是画成这样,名字在它的上面:

消费过程与接收相似,一个消费者通常是一个等着接受消息的程序,我们使用"C"来描述:

注意,那生产者,消费者和代理者不需要一定在一个机器上,事实上,大多数应用程序中,他们并不在一个机器上。

"Hello World"

(使用java客户端)

在这部分指南中,我们将要使用java写两个程序;一个发送简单消息的生产者和一个接收消息并输出出来的消费者。我们会忽视掉一些Java API的细节,为了开始仅仅精选在这简单的事情上,这是一个"Hello World"消息。

Java 客户端库 RabbitMQ 遵循AMQP协议,那是一个开放的,并且通用的消息协议。在不同语言中有数种AMQP客户端,我们使用由RabbitMQ提供的Java客户端。 下载客户端库包,检验签名,将它解压缩到你的工作路径,从解压到的路径中提取JAR文件:

$ unzip rabbitmq-java-client-bin-*.zip
$ cp rabbitmq-java-client-bin-*/*.jar ./

(RabbitMQ Java客户端也存在Maven中央库中,groupIdcom.rabbitmq,artifactIdamqp-client.)

现在我们已经有了Java客户端和依赖文件,我们可以写一些代码了。

发送

我们将会让我们的消息发送者发送消息,我们的接收者接收消息。发送者连接到RabbitMQ上,发送一个简单的消息,然后退出。

Send.java,我们需要引入一些类:

import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;

建立这个类,为队列命名:

public class Send {

  private final static String QUEUE_NAME = "hello";

  public static void main(String[] argv)
throws java.io.IOException {
...
}
}

接着,我们创建一个服务器的连接:

    ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();

抽象的socket连接,注意协议版本的处理以及授权,诸如此类的事情。 这里我们连接到本地机器上的代理,因此它是localhost。如果我们想连接到不同机器上的代理,只需要说明它的主机名和IP地址。

接下来我们创建一个通道,获取操作的大多数API都位于这上。

对于发送,我们必须声明一个发送队列,然后我们把消息发送到这个队列上:

channel.queueDeclare(QUEUE_NAME, false, false, false, null); String message = "Hello World!"; channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); System.out.println(" [x] Sent '" + message + "'");

Declaring a queue is idempotent - it will only be created if it doesn't exist already. The message content is a byte array, so you can encode whatever you like there.

Lastly, we close the channel and the connection; 声明一个队列是幂等的,仅仅在要声明的队列不存在时才创建。消息内容是二进制数组,所以你可以随你喜好编码。

channel.close(); connection.close();

Here's the whole Send.java class.

发送没有起作用

如果你是第一次使用RabbitMQ并且你没有看到"Sent"消息,你可能抓耳挠腮的想到底是哪里出的问题。可能是代理启动时没有足够空间(默认 它需要至少1Gb 空间),因此拒绝接受消息。通过检查代理的日志文件来确定这个问题,必要情况下可以降低限制大小。配置文件的文档将会告诉你怎样设置disk_free_limit

接收

上面代码是构建我们的发送者。我们的接收者是从RabbitMQ中提取消息,所以不像发送者那样发送一个简单的消息,我们需要一直运行监听消息并且输出消息。

Recv.java中的代码有与Send中几乎相同的引用:

import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.Connection; import com.rabbitmq.client.Channel; import com.rabbitmq.client.QueueingConsumer;

这额外的QueueingConsumer类是用来缓存从服务器那里发出来的信息。

跟创建发送者相同,我们打开一个连接和一个通道,声明一个我们要消费的队列。注意要与发送的队列相匹配。

public class Recv {

  private final static String QUEUE_NAME = "hello";

  public static void main(String[] argv)
throws java.io.IOException,
java.lang.InterruptedException { ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel(); channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
...
}
}

注意我们在这里同样声明了一个队列。以为我们可能在发送者之前启动接收者,在我们从中获取消息之前我们想要确定这队列是否真实存在。 我们通知服务器通过此队列给我们发送消息。因此服务器会异步的给我们推送消息,在这里我们提供一个回调对象用来缓存消息,直到我们准备好再使用它们。这就是QueueingConsumer所做的事。

QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(QUEUE_NAME, true, consumer); while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
}

QueueingConsumer.nextDelivery()在另一个来自服务器的消息到来之前它会一直阻塞着。

这是整个Recv.java类。

把所有放在一起

你可以在RabbitMQ Java客户端的类路径上编译这些文件:

$ javac -cp rabbitmq-client.jar Send.java Recv.java

为了运行它们,你需要rabbitma-client.jar和它在类路径上的的依赖文件。在一个终端上,运行发送者:

$ java -cp .:commons-io-1.2.jar:commons-cli-1.1.jar:rabbitmq-client.jar Send

然后,运行接收者:

$ java -cp .:commons-io-1.2.jar:commons-cli-1.1.jar:rabbitmq-client.jar Recv

在windows环境中,我们使用分号代替冒号来分隔类路径上的选项。

接收者将会输出从RabbitMQ中获取到来自发送者的消息。接收者会一直保持运行,等待消息(使用Ctrl-C停止),所以试着用另一个终端运行发送者。 如果你想检验队列,试着使用rabbitmqctl list_queues0

Hello World!

时间移动到第二部分,构建一个简单的工作队列。

提示 为了保存输入,你可以将类路径设置到环境变量中

\$ export CP=.:commons-io-1.2.jar:commons-cli-1.1.jar:rabbitmq-client.jar
\$ java -cp $CP Send

或者在 Windows环境中:

\> set CP=.;commons-io-1.2.jar;commons-cli-1.1.jar;rabbitmq-client.jar
\> java -cp %CP% Send

转载RabbitMQ入门(1)--介绍的更多相关文章

  1. 转载RabbitMQ入门(3)--发布和订阅

    发布和订阅 (使用java 客户端) 在先前的指南中,我们创建了一个工作队列.这工作队列后面的假想是每一个任务都被准确的传递给工作者.在这部分我们将会做一些完全不同的事情–我们将一个消息传递给多个消费 ...

  2. 转载RabbitMQ入门(6)--远程调用

    远程过程调用(RPC) (使用Java客户端) 在指南的第二部分,我们学习了如何使用工作队列将耗时的任务分布到多个工作者中. 但是假如我们需要调用远端计算机的函数,等待结果呢?好吧,这又是另一个故事了 ...

  3. 转载RabbitMQ入门(2)--工作队列

    工作队列 (使用Java客户端) 在这第一指南部分,我们写了通过同一命名的队列发送和接受消息.在这一部分,我们将会创建一个工作队列,在多个工作者之间使用分布式时间任务. 工作队列(亦称:任务队列)背后 ...

  4. 转载RabbitMQ入门(5)--主题

    主题(topic) (使用Java客户端) 在先前的指南中我们改进了我们的日志系统.取代使用fanout类型的交易所,那个仅仅有能力实现哑的广播,我们使用一个direct类型的交易所,获得一个可以有选 ...

  5. 转载RabbitMQ入门(4)--路由

    路由 (使用Java客户端) 在先前的指南中,我们建立了一个简单的日志系统.我们可以将我们的日志信息广播到多个接收者. 在这部分的指南中,我们将要往其中添加一个功能-让仅仅订阅一个消息的子集成为可能. ...

  6. RabbitMQ 入门系列:5、基础编码:交换机的进阶介绍及编码方式。

    系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...

  7. [转]RabbitMQ入门教程(概念,应用场景,安装,使用)

    原文地址:https://www.jianshu.com/p/dae5bbed39b1 RabbitMQ 简介 RabbitMQ是一个在AMQP(Advanced Message Queuing Pr ...

  8. .NET 环境中使用RabbitMQ RabbitMQ与Redis队列对比 RabbitMQ入门与使用篇

    .NET 环境中使用RabbitMQ   在企业应用系统领域,会面对不同系统之间的通信.集成与整合,尤其当面临异构系统时,这种分布式的调用与通信变得越发重要.其次,系统中一般会有很多对实时性要求不高的 ...

  9. RabbitMQ入门教程(十七):消息队列的应用场景和常见的消息队列之间的比较

    原文:RabbitMQ入门教程(十七):消息队列的应用场景和常见的消息队列之间的比较 分享一个朋友的人工智能教程.比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看. 这是网上的一篇教程写的很好,不知原作 ...

随机推荐

  1. ssh连接慢

    suse刚装完,开始用ssh的时候,总会遇到这样的问题:输入了用户名以后,等半天才出输入密码的框,很是急人.这是dns反查造成的.解决方法:编辑 /etc/ssh/sshd_conf , 将 #Use ...

  2. hdu 3807

    很好的思路     枚举有多少人有ipad 判是否满足题目给出的条件 #include <iostream> #include <cstring> #include <c ...

  3. 2015年最新中国知网CNKI免费账号直接入口

    以下是Free9免费资源网小编收集整理的2015年最新中国知网CNKI免费账号直接入口,现免费分享给大家(仅供测试使用),此类文献数据库资源有时效性,希望对您的学习.工作上有所帮助! 中国知网直接入口 ...

  4. 2014多校第一场A题 || HDU 4861 Couple doubi

    题目链接 题意 : 有K个球,给你一个数P,可以求出K个值,(i=1,2,...,k) : 1^i+2^i+...+(p-1)^i (mod p).然后女朋友先取,再xp取,都希望赢,如果女朋友能赢输 ...

  5. hdu 4315 Climbing the Hill 博弈论

    题意:有n个人爬山,山顶坐标为0,其他人按升序给出,不同的坐标只能容纳一个人(山顶不限),Alice和Bob轮流选择一个人让他移动任意步,但不能越过前面的人,且不能和前面一个人在相同的位置.现在有一个 ...

  6. 【Linux高频命令专题(8)】五大查询命令

    find 格式 find 路径 -命令参数 [输出形式] 路径:告诉find在哪儿去找你要的东西 命令参数:参考下面 输出形式:输出形式很多,-print,-printf,-print,-exec,- ...

  7. 2014-9-17二班----9 web project

    http://localhost:8080/rwkj1/indexServlet             跳转                    http://localhost:8080/rwk ...

  8. Android:PopupWindow简单弹窗改进版

    Android:PopupWindow简单弹窗 继续上一节的内容,改进一下,目标是点击菜单后把菜单收缩回去并且切换内容,我使用的是PopupWindow+RadioGroup public class ...

  9. Intellij IDEA创建javaWeb以及Servlet简单实现

    1.创建web工程 File --> New --> Project...

  10. MyEclipse 常用设置

    1.指定本机java环境 Windows-->preferences-->java-->Insetallel JREs 右侧 单击ADD-->standard VM--> ...