简介

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)

RabbitMQ之HelloWorld【译】的更多相关文章

  1. 【RabbitMQ】HelloWorld

    初识RabbitMQ RabbitMQ是一个消息代理人.它的主要目的很简单:接受并推送消息.我们可以将它理解为一个邮局:当你邮寄一封邮件到邮箱里,可以非常确定邮递员会将它送到收件人手中.打这种比方来将 ...

  2. 五.Spring与RabbitMQ集成--HelloWorld

    spring对RabbitMQ做了很好的集成,我们称之为spring AMQP,其官方文档写得十分详尽,文档地址:https://docs.spring.io/spring-amqp/referenc ...

  3. 六.Spring与RabbitMQ集成--HelloWorld

    spring对RabbitMQ做了很好的集成,我们称之为spring AMQP,其官方文档写得十分详尽,文档地址:https://docs.spring.io/spring-amqp/referenc ...

  4. RabbitMQ 入门 Helloworld

    1.介绍 RabbitMQ 是信息传输的中间者.本质上,他从生产者(producers)接收消息,转发这些消息给消费者(consumers).换句话说,他能够按根据你指定的规则进行消息转发.缓冲.和持 ...

  5. RabbitMQ 入门 Helloworld -摘自网络

    本系列教程主要来自于官网入门教程的翻译,然后自己进行了部分的修改与实验,内容仅供参考. “Hello world” of RabbitMQ 1.Windows下RabbitMQ的安装 下载Erlang ...

  6. RabbitMQ之Helloworld

    RabbitMQ介绍 RabbitMQ是一个消息代理.它的核心原理非常简单:接收和发送消息. 专有名词 生产(Producing)意思就是发送.发送消息的程序就是一个生产者(producer).我们一 ...

  7. RabbitMQ入门HelloWorld(C#)(翻译)

    介绍 先决条件 本教程假定RabbitMQ已安装并在标准端口(5672)上的本地主机上运行.如果您使用不同的主机,端口或凭据,连接设置将需要调整. 在哪里得到帮助 如果您在阅读本教程时遇到困难,可以  ...

  8. RabbitMQ之远程过程调用(RPC)【译】

    在第二个教程中,我们学习了如何使用工作队列在多个worker之间分配耗时的任务. 但是如果我们需要在远程计算机上运行功能并等待结果呢?嗯,这是另外一件事情,这种模式通常被称为远程过程调用(RPC). ...

  9. RabbitMQ之主题(Topic)【译】

    在上一节中,我们改进了我们的日志系统,替换使用fanout exchange仅仅能广播消息,使得选择性的接收日志成为可能. 虽然使用direct exchange改进了我们的系统,但是它仍然由他的局限 ...

随机推荐

  1. linux 基本命令学习

    原文: https://www.oschina.net/translate/useful-linux-commands-for-newbies?lang=chs&p=2

  2. auto_ptr

    1. int *pi = new int(1024); delete pi; // 释放pi指向的int对象占用的内存空间 pi = 0; // 将pi设置为0,不指向任何东西,为Null 注意:删除 ...

  3. Leet Code OJ 226. Invert Binary Tree [Difficulty: Easy]

    题目: Invert a binary tree. 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 / \ / \ 9 6 3 1 思路分析: 题意是将二叉树全部左右子数 ...

  4. 同步网络时间到linux服务器(先修改时区再进行同步网络时间)

    查看时区:date -R 修改整个系统时区: rm -f /etc/localtime ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 网 ...

  5. leetCode 42.Trapping Rain Water(凹槽的雨水) 解题思路和方法

    Trapping Rain Water Given n non-negative integers representing an elevation map where the width of e ...

  6. Linux环境下c语言静态链接库和动态链接库创建和使用

    库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀. 面对比一下两者: 静态链接库:当要使用时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功, ...

  7. Unity3D开发之Mac OS 开发环境搭建 笔记

    http://www.cnblogs.com/zhaoqingqing/p/3383167.html 首先上几张图: 摸索了一上午,才搞定在模拟器中运行.至于在Iphone真机中运行,虽然有开发者证书 ...

  8. sublime text3 3176激活码

    sublime text3 3176激活码   改host文件 #sublime 127.0.0.1 license.sublimehq.com 127.0.0.1 45.55.255.55 127. ...

  9. ThreadPoolExecutor中策略的选择与工作队列的选择(java线程池)

    工作原理 1.线程池刚创建时,里面没有一个线程.任务队列是作为参数传进来的.不过,就算队列里面有任务,线程池也不会马上执行它们. 2.当调用 execute() 方法添加一个任务时,线程池会做如下判断 ...

  10. knockoutjs 静动态数据、行为绑定,计算属性及Sync同步更新 Value值更新事件控制

    data-bind="text: firstName"中data-bind属性是Knockout 用来显示关联UI和viewmodel的桥梁, text 表示把绑定的文本赋值给DO ...