zoukankan      html  css  js  c++  java
  • RabbitMQ之HelloWorld【译】

    简介

    RabbitMQ是一个消息代理,主要的想法很简单:它接收并转发消息。你可以把它当做一个邮局,当你发送邮件到邮筒,你相信邮差先生最终会将邮件投递给收件人。RabbitMQ在这个比喻里,是一个邮筒,邮局和一个邮递员。
    RabbitMQ和邮局最大的不同是,RabbitMQ不处理纸张,而是接收、存储和转发数据的二进制形式。
    RabbitMQ和普通消息,使用的一些术语。
    生产:意味着发送,发送消息的程序是生产者,生产者如下:

    ![](http://images2015.cnblogs.com/blog/658141/201608/658141-20160809231101981-751146404.png)

    队列:是一个邮箱的名称。它在RabbitMQ里面。虽然消息流经RabbitMQ和应用程序,但是他们只能存储在队列里面。一个队列不受任何限制的约束,只要你喜欢你可以存储尽可能多的东西,它本质上是一个无限的缓冲区。很多生产者可以发送消息到一个队列,很多消费者可以从一个队列获取数据。队列如下:

    ![](http://images2015.cnblogs.com/blog/658141/201608/658141-20160809231119246-778373077.png)

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

    ![](http://images2015.cnblogs.com/blog/658141/201608/658141-20160809231132746-118059440.png)

    注意:生产者、消费者和代理不一定在一台机器上,事实上很多应用中也是如此。

    HelloWorld

    下面我们将用Java编写两个程序,生产者发送一个消息,消费者接收消息并打印出来。

    在下图中,”P“是我们的生产者,”C“是我们的消费者,在中间的盒子是一个队列——即RabbitMQ维持的一个消息缓冲区。

    ![](http://images2015.cnblogs.com/blog/658141/201608/658141-20160809231148652-591142369.png)

    The Java client library
    RabbitMQ支持很多种协议,本教程使用AMQP 0-9-1,这是一个开发的通用的消息协议,RabbitMQ的客户端支持很多种语言,这里我们将使用RabbitMQ提供的Java客户端。

    下载客户端库包,并解压到工作目录:

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

    当然,RabbitMQ也在maven中央仓库中:

    <dependency>
        <groupId>com.rabbitmq</groupId>
        <artifactId>amqp-client</artifactId>
        <version>3.6.1</version>
    </dependency>
    

    现在我们有了Java客户端和依赖,我们可以写一点代码了。

    发送(Sending)

    我们称呼我们的消息发送者为send,接受者为recv,发送者将连接到RabbitMQ,发送一条消息,然后退出。

    ![](http://images2015.cnblogs.com/blog/658141/201608/658141-20160809231302574-525128259.png)
    在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连接,这里我们在本地连接上代理,如果我们想连接其他机器上的代理,我们可以改变name和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();
    

    以上就是Send.java的所有代码。
    tips:
    send不管用!在发送消息之后,在RabbitMQ的后台并没有看到发送消息,你可能认为是程序错了,也许是代理没有足够的空间了(默认是需要1G的),所以拒绝接受消息。检查代理的logfile确认原因所在。然后去配置文件设置disk_free_limit即可。

    接收(Receiving)

    我们的接受者从RabbitMQ拉取消息,所以不像发送一条消息的发送者,我们必须保持监听,然后打印出来。

    ![](http://images2015.cnblogs.com/blog/658141/201608/658141-20160809231320793-15208918.png)
    recv和send的import差不多:
    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;
    

    DefaultConsumer实现了Consumer接口——我们用来缓冲服务推给我们的消息。
    实现和sender差不多,我们打开一个连接和通道,定义一个我们即将消费的队列,和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");
        ...
        }
    }
    

    这里我们定义了一个队列,因为我们也许会在sender之前启动receiver,我们需要确认这个队列在我们消费之前就已经存在了。
    我们让服务从队列里面给我们传递消息,自从他将要异步的推送消息,我们提供了一个缓存消息的回调方法,知道我们去用他,这就是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);
    

    以上就是全部的Recv.java。

    原文地址:https://www.rabbitmq.com/tutorials/tutorial-one-java.html

    代码地址:https://github.com/aheizi/hi-mq

    相关:
    1.RabbitMQ之HelloWorld
    2.RabbitMQ之任务队列
    3.RabbitMQ之发布订阅
    4.RabbitMQ之路由(Routing)
    5.RabbitMQ之主题(Topic)
    6.RabbitMQ之远程过程调用(RPC)

  • 相关阅读:
    AcWing 1018. 最低通行费
    蓝桥杯赛第10届省赛
    P5745 【深基附B例】区间最大和
    P3383 【模板】线性筛素数
    第12届蓝桥杯赛国赛 小蓝买瓜子
    P4715 【深基16.例1】淘汰赛
    AcWing 1015. 摘花生
    第12届蓝桥杯赛省赛 种菜的最大价值
    linq to sql初步
    汇编语言学习笔记接收鼠标消息
  • 原文地址:https://www.cnblogs.com/aheizi/p/5755021.html
Copyright © 2011-2022 走看看