RabbitMQ学习笔记二:Java实现RabbitMQ
本地安装好RabbitMQ Server后,就可以在Java语言中使用RabbitMQ了。
RabbitMQ是一个消息代理,从“生产者”接收消息并传递消息至“消费者”,期间可根据规则路由、缓存、持久化消息。“生产者”也即message发送者以下简称P,相对应的“消费者”乃message接收者以下简称C,message通过queue由P到C,queue存在于RabbitMQ,可存储尽可能多的message,多个P可向同一queue发送message,多个C可从同一queue接收message。
几个关键概念:
Broker:简单来说就是消息队列服务器实体。
Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。
Queue:消息队列载体,每个消息都会被投入到一个或多个队列。
Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来。
Routing Key:路由关键字,exchange根据这个关键字进行消息投递。
vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。
producer:消息生产者,就是投递消息的程序。
consumer:消息消费者,就是接受消息的程序。
channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。
由Exchange,Queue,RoutingKey三个才能决定一个从Exchange到Queue的唯一的线路。
消息队列的使用过程大概如下:
(1)客户端连接到消息队列服务器,打开一个channel。
(2)客户端声明一个exchange,并设置相关属性。
(3)客户端声明一个queue,并设置相关属性。
(4)客户端使用routing key,在exchange和queue之间建立好绑定关系。
(5)客户端投递消息到exchange。
现在,可以上代码了。首先,是在项目中加入需要的jar包,我使用的是maven项目,直接配置maven及可:
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>3.0.4</version>
</dependency>
后面还会用到的jar包,配置如下
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
先写一个类,将产生产者和消费者统一为 EndPoint类型的队列。不管是生产者还是消费者, 连接队列的代码都是一样的,这样可以通用一些。
package cn.com.shopec.rabbitmq; import java.io.IOException; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory; public abstract class EndPoint { protected Channel channel; protected Connection connection; protected String endPointName; public EndPoint(String endpointName) throws IOException
{
this.endPointName = endpointName; // Create a connection factory
ConnectionFactory factory = new ConnectionFactory(); // 与RabbitMQ Server建立连接
// 连接到的broker在本机localhost上
factory.setHost("localhost"); // getting a connection
connection = factory.newConnection(); // creating a channel
channel = connection.createChannel(); // declaring a queue for this channel. If queue does not exist,
// it will be created on the server.
// queueDeclare的参数:queue 队列名;durable true为持久化;exclusive 是否排外,true为队列只可以在本次的连接中被访问,
// autoDelete true为connection断开队列自动删除;arguments 用于拓展参数
channel.queueDeclare(endpointName, false, false, false, null);
} /**
* 关闭channel和connection。并非必须,因为隐含是自动调用的。
* @throws IOException
*/
public void close() throws IOException
{
this.channel.close();
this.connection.close();
}
}
生产者类的任务是向队列里写一条消息
package cn.com.shopec.rabbitmq; import java.io.IOException;
import java.io.Serializable; import org.apache.commons.lang.SerializationUtils; public class Producer extends EndPoint { public Producer(String endPointName) throws IOException
{
super(endPointName);
} public void sendMessage(Serializable object) throws IOException
{
channel.basicPublish("", endPointName, null, SerializationUtils.serialize(object));
}
}
消费者可以以线程方式运行,对于不同的事件有不同的回调函数,其中最主要的是处理新消息到来的事件。
package cn.com.shopec.rabbitmq; import java.io.IOException;
import java.util.HashMap;
import java.util.Map; import org.apache.commons.lang.SerializationUtils; import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.ShutdownSignalException; public class QueueConsumer extends EndPoint implements Runnable, Consumer { public QueueConsumer(String endPointName) throws IOException
{
super(endPointName);
} public void run()
{
try
{
// start consuming messages. Auto acknowledge messages.
channel.basicConsume(endPointName, true, this);
}
catch (IOException e)
{
e.printStackTrace();
}
} /**
* Called when consumer is registered.
*/
public void handleConsumeOk(String consumerTag)
{
System.out.println("Consumer " + consumerTag + " registered");
} /**
* Called when new message is available.
*/
public void handleDelivery(String consumerTag, Envelope env, BasicProperties props, byte[] body) throws IOException
{
Map map = (HashMap) SerializationUtils.deserialize(body);
System.out.println("Message Number " + map.get("message number") + " received."); } public void handleCancel(String consumerTag)
{
} public void handleCancelOk(String consumerTag)
{
} public void handleRecoverOk(String consumerTag)
{
} public void handleShutdownSignal(String consumerTag, ShutdownSignalException arg1)
{
}
}
测试类中,先运行一个消费者线程,然后开始产生大量的消息,这些消息会被消费者取走。
package cn.com.shopec.rabbitmq; import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap; public class Main { public Main() throws Exception
{ // 创建消费者,即消息接收者,并启动线程
QueueConsumer consumer = new QueueConsumer("queue");
Thread consumerThread = new Thread(consumer);
consumerThread.start(); // 创建生产者,即消息发送者
Producer producer = new Producer("queue"); // 循环发送消息
for (int i = 0; i < 20; i++)
{
HashMap message = new HashMap();
message.put("message number", i);
producer.sendMessage(message);
System.out.println("Message Number " + i + " sent.");
}
} /**
* @param args
* @throws SQLException
* @throws IOException
*/
public static void main(String[] args) throws Exception
{
new Main();
}
}
运行结果:
Consumer amq.ctag-8TFduKUwrE1I8iT2L5DaZg registered
Message Number 0 sent.
Message Number 1 sent.
Message Number 2 sent.
Message Number 3 sent.
Message Number 4 sent.
Message Number 5 sent.
Message Number 6 sent.
Message Number 7 sent.
Message Number 8 sent.
Message Number 9 sent.
Message Number 10 sent.
Message Number 11 sent.
Message Number 12 sent.
Message Number 13 sent.
Message Number 14 sent.
Message Number 15 sent.
Message Number 16 sent.
Message Number 17 sent.
Message Number 18 sent.
Message Number 19 sent.
Message Number 0 received.
Message Number 1 received.
Message Number 2 received.
Message Number 3 received.
Message Number 4 received.
Message Number 5 received.
Message Number 6 received.
Message Number 7 received.
Message Number 8 received.
Message Number 9 received.
Message Number 10 received.
Message Number 11 received.
Message Number 12 received.
Message Number 13 received.
Message Number 14 received.
Message Number 15 received.
Message Number 16 received.
Message Number 17 received.
Message Number 18 received.
Message Number 19 received.
RabbitMQ学习笔记二:Java实现RabbitMQ的更多相关文章
- 官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群
在第二节我们进行了RabbitMQ的安装,现在我们就RabbitMQ进行集群的搭建进行学习,参考官网地址是:http://www.rabbitmq.com/clustering.html 首先我们来看 ...
- rabbitMQ学习笔记(二) 简单的发送与接收消息 HelloWorld
首先要下载rabbitmq的javaClient库,然后加入到项目中,下载地址为:http://www.rabbitmq.com/releases/rabbitmq-java-client/v3.1. ...
- RabbitMQ学习笔记(5)----RabbitMQ整合Spring
在Spring AMQP项目中Spring也提供了对RabbitMQ的支持,这里在之前学习SpringBoot的时候也整合过,但是今天这里使用的Spring的xml配置来整个rabbit. Sprin ...
- RabbitMQ学习笔记(4)----RabbitMQ Exchange(交换机)的使用
1. fanout模式 1.1 Publish/Subscribe(发布/订阅)结构图 上图表示一个消费者消费消息之后,不讲消息直接存储到队列,而是使用两个消费者各自声明一个队列,将各自的对应的队列与 ...
- RabbitMQ学习笔记(3)----RabbitMQ Worker的使用
1. Woker队列结构图 这里表示一个生产者生产了消息发送到队列中,但是确有两个消费者在消费同一个队列中的消息. 2. 创建一个生产者 Producer如下: package com.wangx.r ...
- RabbitMQ学习笔记(2)----RabbitMQ简单队列(Hello World)的使用
1. 简单队列结构图 2. 引入依赖 pom.xml文件 <dependency> <groupId>com.rabbitmq</groupId> <arti ...
- RabbitMQ学习笔记(八、RabbitMQ总结)
1.什么是消息中间件 Message Queue Middleware,简称MQ,是一种利用高效可靠的消息传递机制进行与平台无关的数据交互的技术. 2.MQ的作用 异步:类似于短信业务,将需要发送的消 ...
- .NET之RabbitMQ学习笔记(二)-安装
安装 1.安装erlang语言环境 因为rabbitmq是基于erlang进行开发,所以需要安装相应的依赖环境,学习中用到的erlang包下载地址:http://www.erlang.org/down ...
- rabbitMq 学习笔记(二) 备份交换器,过期时间,死信队列,死信队列
备份交换器 备份交换器,英文名称为 Altemate Exchange,简称庙,或者更直白地称之为"备胎交换器". 生产者在发送消息的时候如果不设置 mandatory 参数, 那 ...
随机推荐
- Navicat连接Linux系统下的Mysql数据库
1 . 进入Linux机器 , 登录并进入mysql如果没有安装mysql,参照 https://blog.csdn.net/weixin_35353187/article/details/81712 ...
- abandon, abbreviation
abandon 近/反义词: continue, depart, desert (做动词时读作diˈzəːt), discard, give up, quit, surrender搭配: altoge ...
- acid, acknowledge, acquaint
acid sulphuric|hydrochloric|nitric|carbolic|citric|lactic|nucleic|amino acid: 硫|盐|硝|碳|柠檬|乳|核|氨基酸 王水是 ...
- 大数据学习day28-----hive03------1. null值处理,子串,拼接,类型转换 2.行转列,列转行 3. 窗口函数(over,lead,lag等函数) 4.rank(行号函数)5. json解析函数 6.jdbc连接hive,企业级调优
1. null值处理,子串,拼接,类型转换 (1) 空字段赋值(null值处理) 当表中的某个字段为null时,比如奖金,当你要统计一个人的总工资时,字段为null的值就无法处理,这个时候就可以使用N ...
- Reactor之发射器(Flux、Mono)转换操作函数
数据合并函数 由于业务需求有的时候需要将多个数据源进行合并,Reactor提供了concat方法和merge方法: concat public static <T> Flux<T&g ...
- idea集成开发工具快捷键大全
1 执行(run) alt+r 2 提示补全 (Class Name Completion) ...
- DuiLib逆向分析の按钮事件定位
目录 DuiLib逆向分析の按钮事件定位 0x00 前言 DuiLib介绍 DuiLib安装 DuiLib Hello,World! Duilib逆向分析之定位按钮事件 碎碎念 第一步:获取xml布局 ...
- hbuilder打包app基本流程
声明:本文可能用到一些工具和第三方网站,都是为了达到目的而使用的工具,绝不含有广告成分 1.下载.最新的Hbuilder X貌似不能直接创建移动app了(自己不会用),建议旧版.可去腾某讯软件中心下载 ...
- [BUUCTF]PWN——[HarekazeCTF2019]baby_rop2
[HarekazeCTF2019]baby_rop2 题目附件 步骤: 例行检查,64位,开启了nx保护 运行了一下程序,了解大概的执行情况 64位ida载入,shift+f12检索程序里的字符串,没 ...
- OpenWrt之关闭IPv6
目录 OpenWrt之关闭IPv6 1.前言 2.WAN口设置 3.LAN口设置 4.保存并应用 5.防火墙设置 6.DHCP/DNS设置 1)SSH连接路由器 2)输入第一条命令,按回车执行 3)输 ...