RabbitMQ官方入门教程中文版(java)第一部分 Hello World

RabbitMQ是一种消息中间件:简单来说,它可以负责接收和发送消息。你可以把RabbitMQ想象成是一个邮局:当你想寄一封信的时候你会把信放进邮箱里,因为你确信邮递员会帮你把这封信送到收件人的手中。在这个比喻中,RabbitMQ扮演的就是邮箱,邮局和邮递员这样的角色。

要说起RabbitMQ和邮局最大的不同,那应该是MQ并不是处理纸质信息,取而代之的是负责接收,存储和发送二进制数据块——或者是我们常说的 “消息” 。

通常来讲,我们谈到RabbitMQ或者说消息中间件时会使用一些行话,我们在此先了解一下:

生产意味着只进行发送工作,所以一个发送消息的程序我们称之为生产者。

     

队列我们可以看作是在RabbitMQ中充当着邮箱的角色。虽然消息流在RabbitMQ和应用间传输,但是消息只能保存在队列中。队列仅仅受限于host主机的内存和硬盘的大小,本质上是一个大的消息缓冲区。多个生产者可以给一个队列发送消息,而一个队列也可以被多个消费者消费。队列的图示如下:

消费和接收有着相似的含义,所以消费者就是指那些主要负责等待接收消息的应用

     

值得注意的是,生产者、消费者和中间件不是一定要部署在同一台主机上;事实上,在大多数应用当中都不会部署在同一台机器上,而且一个应用程序既可以是生产者,也可以是消费者。

Hello World!

接下来我们将会使用Java写两个小程序,一个是模拟生产者发送消息,另一个模拟消费者接收消息并且输出出来。我们将会忽略一些java api的细节,专注于快速开始使用rabbitmq。我们要产生的消息为“Hello World”。

在下面的图解中,P代表了生产者,C代表了消费者,中间的框则表示为一个队列。

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

下载rabbitmq client包和依赖包:slf4j apislf4j simple。把下载好的文件复制到工作空间,当然了也可以使用maven中央仓库,这里贴出我在写这篇博文时所使用的依赖:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
</dependency>

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.25</version>
</dependency>

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

需要注意的是对于入门教程来说,slf4j simple的功能已经足够了,但如果是生产环境的话,还是应该使用一些更加成熟的日志管理框架,如logback 

同时,本文是基于RabbitMQ已经正确安装并且运行在localhost和端口5672上,如果在你的本地有自己的设置,那么下文中对应部分需要相应调整。

附上RabbitMQErlang的下载地址

 现在我们完成了客户端和依赖包的下载之后可以开始写一些代码了 。

发送

(P) -> [|||]

生产者会连接到RabbitMQ上,发送一条消息然后退出。

新建一个Send.java,给队列queue起一个名字"hello"

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");
try (Connection connection = factory.newConnection();
     Channel channel = connection.createChannel()) {

}

connection抽象了socket连接,控制协议版本和授权等问题。现在我们是在本地连接中间件,所以host使用localhost就可以了,如果想连接其他机器上的中间件只需要把host改成对应的host name或者ip地址就可以了。

接下来我们创建一个通道channel,其中包含了绝大多数的api。值得注意的是,创建channel的时候我们可以使用try-with-resources语法,connection和channel都实现了Closeable接口,我们就不需要在代码中再写close相关的代码了。

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 + "'");

为了发送,我们还需要声明一个queue,然后我们就可以向这个队列中发布消息,这些都写在try-with-resources声明中。

声明一个queue是幂等性的 —— 当不存在的时候queue才会被创建。而消息内容是一个字节数组,所以你可以在任何地方对它进行解码。

在这里附上官方写的完整版Send.java代码,代码非常简单,就是简单的设置主机地址,然后建立连接,发送了一条字符串消息“Hello World”。如果一切正常没问题的话,你应该会看到如下的结果,表示这条消息已经发送成功了。

此时可以访问http://localhost:15672,这是rabbitmq的本地管理页面,你会看到queues选项中应该有了你刚刚定义的hello队列。

接收

刚刚都是对于生产者的操作。而消费者是从RabbitMQ接收推送消息的,因此与生产者发送单个消息不同,消费者要一直处于运行的状态并且监听消息,这里我们接收消息后做简单的打印处理。

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

  }
}

代码很多地方和生产者相似,打开一个连接和通道,然后声明一个需要消费的队列,队列的名字应该和生产者发布的队列名一样,在这个例子中就是hello。

也许你会问,为什么在消费者中不使用 try-with-resource的方式了呢?那样可以使代码简洁,我们只需要运行程序,然后资源都会自动关闭和退出。这样并不适用于消费者,因为我们希望消费者一直保持active的状态,并且持续监听消息的到达结果。

我们将要告诉服务器向消费者发送队列中的消息。因为服务器是异步的推送消息,我们这消费者中以对象的形式提供一个回调,它会将消息缓冲直到消费者准备好使用该消息。这里就需要用到DelieverCallback类了

DeliverCallback deliverCallback = (consumerTag, delivery) -> {
    String message = new String(delivery.getBody(), "UTF-8");
    System.out.println(" [x] Received '" + message + "'");
};
channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });

这里给出完整的Recv.java的代码。此时运行消费者代码,会在控制台打印出从RabbitMQ接收到的生产者发布的消息,消费者会一直保持运行状态等待消息的到来,想要停止可以按ctrl + C(这里是指通过命令行编译运行,如果是通过ide运行应该有对应的stop按钮),现在你可以试试再去运行刚才的生产者代码,看看消费者这边是否发生了变化。

到这里我们应该就借助RabbitMQ完成了一个简单的生产者——消费者模型,虽然看起来很简单,但是如果是从零搭建环境的话中间难免遇到很多坑和错误,欢迎在留言区留下,大家一起讨论!

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值