热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

RabbitMQ教程:HelloWorld(一)

Introduction介绍Prerequisites先决条件  ThistutorialassumesRabbitMQisinstalledandrunningonlocalh

Introduction

介绍


Prerequisites 先决条件
  This tutorial assumes RabbitMQ is installed and running on localhost on standard port (5672). In case you use a different host, port or credentials, connections settings would require adjusting.
  本教程假定RabbitMQ 已在标准端口(5672)上的localhost上安装并运行。如果您使用不同的主机,端口或凭据,则需要调整连接设置。

Where to get help 哪里可以得到帮助

   If you’re having trouble going through this tutorial you can contact us through the mailing list.
   如果您在阅读本教程时遇到问题,可以 通过邮件列表与我们联系。


   RabbitMQ is a message broker: it accepts and forwards messages. You can think about it as a post office: when you put the mail that you want posting in a post box, you can be sure that Mr. or Ms. Mailperson will eventually deliver the mail to your recipient. In this analogy, RabbitMQ is a post box, a post office and a postman.
   RabbitMQ是一个消息代理:它接受和转发消息。您可以将其视为邮局:当您将要发布的邮件放在邮箱中时,您可以确定邮件先生或Mailperson女士最终会将邮件发送给您的收件人。在这个比喻中,RabbitMQ是邮箱,邮局和邮递员。

   The major difference between RabbitMQ and the post office is that it doesn’t deal with paper, instead it accepts, stores and forwards binary blobs of data ‒ messages.
   RabbitMQ和邮局之间的主要区别在于它不处理纸张,而是接受,存储和转发二进制blob数据 - 消息。

   RabbitMQ, and messaging in general, uses some jargon.
   RabbitMQ和一般的消息传递使用了一些术语。
   Producing means nothing more than sending. A program that sends messages is a producer :
   制作消息的目的 意味着的无非是发送消息。发送消息的应用程序是生产者:

   A queue is the name for a post box which lives inside RabbitMQ. Although messages flow through RabbitMQ and your applications, they can only be stored inside a queue. A queue is only bound by the host’s memory & disk limits, it’s essentially a large message buffer. Many producers can send messages that go to one queue, and many consumers can try to receive data from one queue. This is how we represent a queue:
  队列是RabbitMQ中的邮箱的名称。虽然消息流经RabbitMQ和您的应用程序,但它们只能存储在队列中。甲队列仅由主机的存储器&磁盘限制约束,它本质上是一个大的消息缓冲器。许多生产者可以发送到一个队列的消息,并且许多消费者可以尝试从一个队列接收数据。这就是我们代表队列的方式:

  Consuming has a similar meaning to receiving. A consumer is a program that mostly waits to receive messages:
  消费与接收有类似的意义。一个消费者是一个主要等待接收信息的程序:

在这里插入图片描述
  Note that the producer, consumer, and broker do not have to reside on the same host; indeed in most applications they don’t. An application can be both a producer and consumer, too.
请注意,生产者,消费者和代理不必驻留在同一主机上; 实际上在大多数应用中他们没有。应用程序既可以是生产者也可以是消费者。

  “Hello World”

  (using the Java Client) 使用Java客户端

  In this part of the tutorial we’ll write two programs in Java; a producer that sends a single message, and a consumer that receives messages and prints them out. We’ll gloss over some of the detail in the Java API, concentrating on this very simple thing just to get started. It’s a “Hello World” of messaging.
  在本教程的这一部分中,我们将用Java编写两个程序; 发送单个消息的生产者,以及接收消息并将其打印出来的消费者。我们将掩盖Java API中的一些细节,专注于这个非常简单的事情,只是为了开始。它是消息传递的“Hello World”。

  In the diagram below, “P” is our producer and “C” is our consumer. The box in the middle is a queue - a message buffer that RabbitMQ keeps on behalf of the consumer.
  在下图中,“P”是我们的生产者,“C”是我们的消费者。中间的框是一个队列 - RabbitMQ代表消费者保留的消息缓冲区。

在这里插入图片描述


The Java client library Java客户端库

  RabbitMQ speaks multiple protocols. This tutorial uses AMQP 0-9-1, which is an open, general-purpose protocol for messaging. There are a number of clients for RabbitMQ in many different languages. We’ll use the Java client provided by RabbitMQ.
  RabbitMQ使用多种协议。本教程使用AMQP 0-9-1,它是一种开放的,通用的消息传递协议。RabbitMQ有许多不同语言的客户端。我们将使用RabbitMQ提供的Java客户端。

  Download the client library and its dependencies (SLF4J API and SLF4J Simple). Copy those files in your working directory, along the tutorials Java files.
  下载客户端库 及其依赖项(SLF4J API和 SLF4J Simple)。在您的工作目录中复制这些文件,以及Java教程文件。

  Please note SLF4J Simple is enough for tutorials but you should use a full-blown logging library like Logback in production.
  请注意SLF4J Simple对于教程来说已经足够了,但是您应该使用一个成熟的日志库,比如在生产环境中使用Logback。

  (The RabbitMQ Java client is also in the central Maven repository, with the groupId com.rabbitmq and the artifactId amqp-client.)
  (RabbitMQ Java客户端也在中央Maven存储库中,包含groupId com.rabbitmq和artifactId amqp-client。)

  Now we have the Java client and its dependencies, we can write some code.
  现在我们有了Java客户端及其依赖项,我们可以编写一些代码。


Sending

(P) -> [|||]
  We’ll call our message publisher (sender) Send and our message consumer (receiver) Recv. The publisher will connect to RabbitMQ, send a single message, then exit.
我们将呼叫我们的消息发布者(发送者)发送和我们的消息消费者(接收者) Recv。发布者将连接到RabbitMQ,发送单个消息,然后退出。

In Send.java, we need some classes imported:
在 Send.java中,我们需要导入一些类:

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

Set up the class and name the queue:
设置类并命名队列:

public class Send {private final static String QUEUE_NAME = "hello";public static void main(String[] argv)throws java.io.IOException {...}
}

then we can create a connection to the server:
然后我们可以创建到服务器的连接:

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

  The connection abstracts the socket connection, and takes care of protocol version negotiation and authentication and so on for us. Here we connect to a broker on the local machine - hence the localhost. If we wanted to connect to a broker on a different machine we’d simply specify its name or IP address here.
连接抽象套接字连接,并为我们负责协议版本协商和身份验证等。这里我们连接到本地机器上的代理 - 因此是 本地主机。如果我们想要连接到不同机器上的代理,我们只需在此处指定其名称或IP地址。

  Next we create a channel, which is where most of the API for getting things done resides.
接下来,我们创建一个频道,这是完成任务的大部分API所在的位置。

  To send, we must declare a queue for us to send to; then we can publish a message to the queue:
要发送,我们必须声明一个队列供我们发送; 然后我们可以向队列发布消息:

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.

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();}
}

  Sending doesn’t work! 发送不起作用!

  If this is your first time using RabbitMQ and you don’t see the “Sent” message then you may be left scratching your head wondering what could be wrong. Maybe the broker was started without enough free disk space (by default it needs at least 200 MB free) and is therefore refusing to accept messages. Check the broker logfile to confirm and reduce the limit if necessary. The configuration file documentation will show you how to set disk_free_limit.
如果这是您第一次使用RabbitMQ并且没有看到“已发送”消息,那么您可能会感到头疼,想知道可能出现的问题。也许代理是在没有足够的可用磁盘空间的情况下启动的(默认情况下它至少需要200 MB空闲),因此拒绝接受消息。检查代理日志文件以确认并在必要时减少限制。该配置文件文档会告诉你如何设置disk_free_limit。


Receiving 接收

  That’s it for our publisher. Our consumer is pushed messages from RabbitMQ, so unlike the publisher which publishes a single message, we’ll keep it running to listen for messages and print them out.
  这就是我们的出版商。 我们的消费者是来自RabbitMQ的推送消息,因此与发布单个消息的发布者不同,我们将使其保持运行以侦听消息并将其打印出来。

[|||] -> (C)
  The code (in Recv.java) has almost the same imports as Send:
代码(在Recv.java中)与Send的导入几乎相同:

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;

The extra DefaultConsumer is a class implementing the Consumer interface we’ll use to buffer the messages pushed to us by the server.
额外的DefaultConsumer是一个实现Consumer 接口的类,我们将用它来缓冲服务器推送给我们的消息。

  Setting up is the same as the publisher; we open a connection and a channel, and declare the queue from which we’re going to consume. Note this matches up with the queue that send publishes to.
设置与发布者相同; 我们打开一个连接和一个通道,并声明我们将要消耗的队列。请注意,这与发送到的队列匹配。

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

  Note that we declare the queue here, as well. Because we might start the consumer before the publisher, we want to make sure the queue exists before we try to consume messages from it.
注意,我们也在这里声明队列。因为我们可能会在发布者之前启动使用者,所以我们希望在尝试使用消息之前确保队列存在。

  We’re about to tell the server to deliver us the messages from the queue. Since it will push us messages asynchronously, we provide a callback in the form of an object that will buffer the messages until we’re ready to use them. That is what a DefaultConsumer subclass does.
我们即将告诉服务器从队列中传递消息。因为它会异步地向我们发送消息,所以我们以对象的形式提供一个回调,它将缓冲消息,直到我们准备好使用它们。这就是DefaultConsumer子类的作用。

Consumer consumer = new DefaultConsumer(channel) {@Overridepublic 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. 这是整个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) {@Overridepublic 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);}
}

Putting it all together 把它们放在一起

  You can compile both of these with just the RabbitMQ java client on the classpath:
  您可以在类路径上只使用RabbitMQ java客户端编译这两个:

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

  To run them, you’ll need rabbitmq-client.jar and its dependencies on the classpath. In a terminal, run the consumer (receiver):
要运行它们,您需要rabbitmq-client.jar及其对类路径的依赖性。在终端中,运行消费者(接收者):

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

then, run the publisher (sender): 然后,运行发布者(发件人):

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

On Windows, use a semicolon instead of a colon to separate items in the classpath.
在Windows上,使用分号而不是冒号分隔类路径中的项目。

  The consumer will print the message it gets from the publisher via RabbitMQ. The consumer will keep running, waiting for messages (Use Ctrl-C to stop it), so try running the publisher from another terminal.
消费者将通过RabbitMQ打印从发布者处获得的消息。消费者将继续运行,等待消息(使用Ctrl-C停止消息),因此请尝试从另一个终端运行发布者。


Listing queues

  You may wish to see what queues RabbitMQ has and how many messages are in them. You can do it (as a privileged user) using the rabbitmqctl tool:
您可能希望看到RabbitMQ有哪些队列以及它们中有多少消息。您可以使用rabbitmqctl工具(作为特权用户)执行此操作:

sudo rabbitmqctl list_queues

On Windows, omit the sudo: 在Windows上,省略sudo:

rabbitmqctl.bat list_queues

Time to move on to part 2 and build a simple work queue.
是时候进入第2部分并构建一个简单的工作队列了。


Hint 提示

To save typing, you can set an environment variable for the classpath e.g.
要保存类型,可以为类路径设置环境变量,例如

export CP=.:amqp-client-4.0.2.jar:slf4j-api-1.7.21.jar:slf4j-simple-1.7.22.jar
java -cp $CP Send

or on Windows: 或在Windows上:


set CP=.;amqp-client-4.0.2.jar;slf4j-api-1.7.21.jar;slf4j-simple-1.7.22.jar
java -cp %CP% Send

Production [Non-]Suitability Disclaimer 生产[非]适用性免责声明

  Please keep in mind that this and other tutorials are, well, tutorials. They demonstrate one new concept at a time and may intentionally oversimplify some things and leave out others. For example topics such as connection management, error handling, connection recovery, concurrency and metric collection are largely omitted for the sake of brevity. Such simplified code should not be considered production ready.
请记住,这个和其他教程都是教程。他们一次展示一个新概念,可能会故意过度简化某些事情而忽略其他事物。例如,为了简洁起见,在很大程度上省略了诸如连接管理,错误处理,连接恢复,并发和度量收集之类的主题。这种简化的代码不应被视为生产就绪。

  Please take a look at the rest of the documentation before going live with your app. We particularly recommend the following guides: Publisher Confirms and Consumer Acknowledgements, Production Checklist and Monitoring.
在使用您的应用程序之前,请先查看其余文档。我们特别推荐以下指南:发布者确认和消费者致谢, 生产清单和监控。


Getting Help and Providing Feedback

获得帮助并提供反馈
  If you have questions about the contents of this tutorial or any other topic related to RabbitMQ, don’t hesitate to ask them on the RabbitMQ mailing list.
如果您对本教程的内容或与RabbitMQ相关的任何其他主题有疑问,请不要犹豫,在RabbitMQ邮件列表中询问他们。


Help Us Improve the Docs ❤️

帮助我们改进文档
  If you’d like to contribute an improvement to the site, its source is available on GitHub. Simply fork the repository and submit a pull request. Thank you!
如果您想对网站做出改进,可以在GitHub上找到它的来源。只需分叉存储库并提交拉取请求。谢谢!


推荐阅读
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 本文介绍了Python函数的定义与调用的方法,以及函数的作用,包括增强代码的可读性和重用性。文章详细解释了函数的定义与调用的语法和规则,以及函数的参数和返回值的用法。同时,还介绍了函数返回值的多种情况和多个值的返回方式。通过学习本文,读者可以更好地理解和使用Python函数,提高代码的可读性和重用性。 ... [详细]
  • 本文讨论了在使用PHP cURL发送POST请求时,请求体在node.js中没有定义的问题。作者尝试了多种解决方案,但仍然无法解决该问题。同时提供了当前PHP代码示例。 ... [详细]
  • 本文介绍了利用ARMA模型对平稳非白噪声序列进行建模的步骤及代码实现。首先对观察值序列进行样本自相关系数和样本偏自相关系数的计算,然后根据这些系数的性质选择适当的ARMA模型进行拟合,并估计模型中的位置参数。接着进行模型的有效性检验,如果不通过则重新选择模型再拟合,如果通过则进行模型优化。最后利用拟合模型预测序列的未来走势。文章还介绍了绘制时序图、平稳性检验、白噪声检验、确定ARMA阶数和预测未来走势的代码实现。 ... [详细]
  • 目录1、将mysql数据导出到SQL文件中(数据库存在的情况)2、将现有的sql文件数据导入到数据库中(前提数据库存在) 3、利用Navicat导出SQL文件和导入SQL文件1)从 ... [详细]
  • Introduction(简介)Forbeingapowerfulobject-orientedprogramminglanguage,Cisuseda ... [详细]
  • Thisworkcameoutofthediscussioninhttps://github.com/typesafehub/config/issues/272 ... [详细]
  • [转载]从零开始学习OpenGL ES之四 – 光效
    继续我们的iPhoneOpenGLES之旅,我们将讨论光效。目前,我们没有加入任何光效。幸运的是,OpenGL在没有设置光效的情况下仍然可 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
author-avatar
tt
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有