您的位置:首页 > 其它

RabbitMQ官方教程之一 “创建 hello world!”

2017-07-25 14:14 561 查看
原文链接:http://www.rabbitmq.com/tutorials/tutorial-two-java.html

介绍

RabbitMQ是一个消息代理:它负责接收和转发消息。你可以视它为一个邮局,当你想发送邮件的时间,你可以确信邮递员最终会派发给收件人那里。在这个比喻中,RabbitMQ就是一个邮箱,邮局和邮递员。

RabbitMQ和邮局的主要差异在于它不处理文件,而是接收、存储和转发二进制数据消息。

RabbitMQ和消息通常使用的一些专业术语:

生产(Producing)意味着发送。发送消息的程序就是一个生产者。我们常用P来表示:



队列就是一个位于RabbitMQ里面的邮箱名字。消息是通过你的应用程序和RabbitMQ进行传输,它们能够只存储在一个队列中。队列没有任何限制,你要存储多少消息都可以—-基本上是一个无限的缓冲。多个生产者可以发送消息给同一个队列,而多个消费者可以尝试从同一个队列中接收数据。队列可以用一下标识:



消费者和接收消息有相似的意思。消费者就是一个等待接收(获取)消息的程序。



注意:一般生产者、消费者和代理都不需要部署到同一台主机上,而且很多应用都不会这样做。

创建 “Hello World!”

在这部分的教程中,我们会编写两个Java程序:一个是发送单条消息的生产者程序;另外一个是接收消息并打印出来的消费者程序。我们会掩盖一些Java API中的详细描述,集中关注这个非常简单的程序。发送一个“Hello World!”消息。

在下面的图示中,“P”代表生产者,“C”代表消费者。中间的方块代表一个队列——RabbitMQ代表消费者的消息缓冲区。

java客户端库

RabbitMQ支持多种协议,本教程使用AMQP 0-9-1,它是一个开源的、通用的消息协议。有很多种不同语言编写的RabbitMQ客户端,我们将使用RabbitMQ提供的Java客户端。

下载客户端库及其依赖项(SLF4J APISLF4J Simple)。 复制这些到你的工作目录中得仅仅是教程列举的java文件,依赖需要你自己添加。

请注意Slf4j的例子,对于本教程是足够了,但是你需要在生产环境中使用一个成熟的日志库,例如Logbock

(RabbitMQ的Java客户端也位于Maven中央存储库中,groupId = com.rabbitmq 和 artifactId = amqp-client。)

现在有了Java 客户端和它的相关依赖,我们可以开始写一些代码了。

Sending(发送端)



我们可以通知我们的消息发布者(发送人)Send 和 消息消费者(接收人)Recv 了。这个发布者会连接上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();


Connection对象将socket连接抽象化,封装了协议的版本和身份验证等。在这里,我们通过“localhost”连接上本地机器的代理。如果我们想去连接不同机器的代理,我们可以简单地在这里指出他的名字或者Ip地址。

接下来我们要创建一个消息通道(channel),这是大部分用于完成任务的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 + "'");


声明的队列是幂等的,只有当它不存在时才会被创建。消息的内容是一个二进制数组,因此你可以编码你喜欢的任何东西。

最后,我们关闭通道和连接。

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


Here’s the whole Send.java class.

Sending doesn’t work!

如果这是你第一次使用使用RabbitMQ和你没有看到已发送的消息,然后你也许会抓破头皮想知道是哪里出问题了。也许是代理开启时没有足够的空闲磁盘空间(默认是至少需要200MB的空闲空间),因此拒绝接收消息。检查代理的日志文件去确认和减少需求的限制。这个配置文件会告诉怎样去设置disk_free_limit 。

Receiving(接收端)

上面说的是发布者。消费者将接收从RabbitMQ上推送的消息,因此它不同于发布者发布单条消息,我们将保持它持续运行来监听消息并将它打印出来。



Recv.java 和 Send.java基本需要引用相同的类。

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


这个额外导入的DefaultConsumser是一个实现了Comsumer接口的类,用来缓冲由服务器推送给我们的消息。

设置与Publisher的相同,我们要打开一个连接和一个通道,并且声明一个我们将要消费的队列。注意,这个队列需要匹配Send(发送端)发送用的队列。

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");
...
}
}


注意,我们也可以在这里声明一个队列。因为我们可能会在Publisher(发送者)之前启动Consumer(消费者),我们想要确保在我们尝试从队列中获取消息之前队列已经存在了。

我们还要告诉服务器从队列中分发消息给我们。因为它会异步地推送消息给我们,所以我们提供一个对象形式的回调,该对象会缓冲消息,知道我们准备去使用他们。这就是DefaultConsumer的子类。

Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body)
throws IOException {
String message = new String(body, "UTF-8");
System.out.println(" [x] Received '" + message + "'");
}
};
channel.basicConsume(QUEUE_NAME, true, consumer);


Here’s the whole Recv.java class.

Putting it all together (把他们放在一起)

Send.java的源代码

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

public class Send {

private final static String QUEUE_NAME = "hello";

public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel();

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

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


Recv.java的源代码

import com.rabbitmq.client.*;

import java.io.IOException;

public class Recv {

private final static String QUEUE_NAME = "hello";

public static void main(String[] argv) throws Exception {
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");

Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
throws IOException {
String message = new String(body, "UTF-8");
System.out.println(" [x] Received '" + message + "'");
}
};
channel.basicConsume(QUEUE_NAME, true, consumer);
}
}


你可以在类路径上使用RabbitMQ java客户端来编译它们。

javac -cp amqp-client-4.0.2.jar Send.java Recv.java


运行这两个java文件,你需要在类路径下使用rabbitmq-client.jar和其相关的以来文件。在终端上,运行一个消费者程序(接收这):

java -cp .:amqp-client-4.0.2.jar:slf4j-api-1.7.21.jar:slf4j-simple-1.7.22.jar Recv


然后,运行一个发布者程序

java -cp .:amqp-client-4.0.2.jar:slf4j-api-1.7.21.jar:slf4j-simple-1.7.22.jar Send


在Windows系统上,类路径使用分号而不是冒号来分割每一项。

消费者会打印出从RabbitMQ上获取的消息,这些都是发布者(publisher)发送给RabbitMQ的。消费者会持续运行,等待消息的到来(可以使用 Ctrl + C 来退出它)。因此要尝试从其他种终端上运行发布者。

Listing Queues

你可能想知道RabbitMQ上有什么队列和他们包含了多少个消息,此时,你可以使用rabiitmqctl工具。

sudo rabbitmqctl list_queues


在windows系统上,你忽略掉sudo即可。

rabbitmqctl.bat list_queues
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  RabbitMQ