rabbit MQ(一)

http://www.rabbitmq.com/tutorials/tutorial-one-java.html


 RabbitMQ 是一个消息代理。原理非常简单,即实现消息的接受和转发。RabbitMQ类似一个邮政局,当我们投递邮件到有邮箱的时候,我们相信邮递员会把我们的信件送到目的地。RabbitMQ就类似一个邮箱、邮局和邮递员。RabbitMQ和邮局的最主要区别是没有纸质的信件,RabbitMQ接收、存储、转发二进制数据——消息。

RabbitMQ 通常会使用一下专业术语。

Producing意思是发送。发送消息的程序就是一个生产者,通过下图展示。

 

队列类似邮箱。队列是RabbitMQ的核心。虽然消息通过RabbitMQ在应用之间传输,但是只能在队列中存储。队列不受任何限制,它能够存储很多消息,队列是一个无界缓冲区。很多生产者可以向一个队列发送消息,很多消费者可以从一个队列接收消息。队列可以描绘成下图所示的,队列名字在队列上面。

 

消费者的意思是接收消息。一个消费者程序主要是等待接收消息,可以用字母C来表示消费者。



 

注意,生产者、消费者、和消息服务(broker)不需要在同一台机器上,在大部分场景上并不会存在。

在下面的指南中我们将用java写两个程序,一个简单的发送消息的生产者和一个接收并打印消息的消费者。我们将讨论Java API d的细节,开始只是集中在简单的示例上。创建一个“hello world”.

 
 

下面图种,“P”表示我们的生产者,“C”表示我们的消费者,中间的盒子表示队列,RabbitMQ为消费者保留的消息缓冲区。

 

 
 

java客户端代码库

 

RabbitMQ有多个协议。我们的教程中使用的是AMQP0-9-1,其是一个开放的、多功能的消息协议。针对RabbitMQ有多个不同语言客户端实现。我们使用的是RabbitMQ提供的java客户端。

 

消息发送

我们把我们的消息发送者为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();

连接抽象套接字连接,并为我们处理协议版本协商和认证等。这里我们连接到本地机器上的代理,因此用的是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 + "'");

声明队列是一个幂等的,即只有队列不存在时候才能够创建队列。消息内容是字节数组,所以可用用你喜欢的进行编码。

关闭通道和连接。

    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 1Gb 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的消息,所以她和发送者向服务器发送消息不同,我们保持接收者持续运行并且监听消息,同时把消息打印出

 

 接收者代码引用的类基本和发送者相同:

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;

 额外的默认消费这是实现了Consumer接口的类,我们将使用它缓存消费服务器推送过来的消息。

 实现方式和发送者相同,打开一个连接和一个通道,同时声明我们消费的队列。注意,接收者监听的是发送者推送消息的队列。

 

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

 注意我们在接受者端也声明的队列。这是因为我们可能在发送者之前启动接收者,我们要确保从队列消费之前队列是已经存在的。

我们告诉服务器把队列的消息发送给我们。因此服务器将异步的向我们推送消息。我们以对象形式提供了一个回调,用来缓存消息,等待我们进行消费。这就是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);



 

 

 

可以在classpath中增加RabbitMQ java 客户端来编译发送者和接收者代码:

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

为了运行上述代码,需要 rabbitmq-client.jar  同时添加到classpath中,运营发送者:

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

 

 运行接收者:

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

 

在windows系统中,classpath中用分号代替冒号

接收者会打印通过RabbitMQ接收的消息,接收者会一直运行等待消息(可以通过Ctrl+C停止),所有可以从其他终端运行发送者。

 

如果想查看队列,可以使用rabbitmqctl list_queues

 

提示:

为了少打字,可以设置一个类似下面的环境变量:

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

 

或者在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

 

猜你喜欢

转载自yangyingda2008.iteye.com/blog/2359231