RabbitMQ入门,helloworld

1、Rabbitmq介绍

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是一个message broker:它接受和转发消息。你可以把它想象成一个邮局:当你把你想要发布的邮件放在一个邮筒里时,你可以确定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和邮局之间的主要区别在于,它不处理纸张,而是接受、存储和转发二进制数据消息。

RabbitMQ, and messaging in general, uses some jargon.

RabbitMQ和消息传递通常使用一些术语。

Producing means nothing more than sending. A program that sends messages is a producer :

Producing的意思就是(无非是)发送。一个发送消息的程序是一个生产者:

                                                         

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:

Consuming也有类似接收的含义。消费者是一个主要等待接收消息的程序:

                                                                  

Note that the producer, consumer, and broker do not have to reside on the same host; indeed in most applications they don't.

请注意,生产者、消费者和代理不需要驻留在同一个主机上;事实上,在大多数应用中,它们都没有。

 

2、"Hello World"

(using the Java Client)

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代表消费者保存的消息缓冲区。

                                                           (P) -> [|||] -> (C)

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.

我们将调用我们的消息发布者(发送者)发送和我们的消息使用者(接收器)接受。发布者将连接到RabbitMQ,发送一条消息,然后退出。

In Send.java, we need some classes imported:

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.

连接抽象了socket(套接字)连接,并负责协议版本的协商和认证,等等。在这里,我们连接到本地机器上的代理——因此是localhost。如果我们想要连接到另一台机器上的代理,我们只需在这里指定它的名称或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.

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:

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是一个实现消费者界面的类,我们将使用它来缓冲服务器推送给我们的消息。

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 sendpublishes to.

设置是与发布者一样的;我们打开一个连接和一个通道,并声明我们将要消费的队列。注意这与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");
    ...
    }
}

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) {
  @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.

本文翻译自http://www.rabbitmq.com/tutorials/tutorial-one-java.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值