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 参数, 那 ...
随机推荐
- Hadoop运行jar包报错java.lang.Exception: java.lang.ArrayIndexOutOfBoundsException: 1
错误信息: java.lang.Exception: java.lang.ArrayIndexOutOfBoundsException: 1 at org.apache.hadoop.mapre ...
- 基于MQTT协议实现远程控制的"智能"车
智能,但不完全智能 虽然我不觉得这玩意儿有啥智能的,但都这么叫就跟着叫喽. 时隔好几天才写的 其实在写这篇博文的时候我已经在做升级了,并且已经到了中后期阶段了. 主要是业余时间做着玩,看时间了. 规格 ...
- Angular 组件通信的三种方式
我们可以通过以下三种方式来实现: 传递一个组件的引用给另一个组件 通过子组件发送EventEmitter和父组件通信 通过serive通信 1. 传递一个组件的引用给另一个组件 Demo1 模板引用变 ...
- 2.ElasticSearch集群的搭建
1.创建elasticsearch-cluster文件夹,在内部复制三个elasticsearch服务 2.修改elasticsearch-cluster\node*\config\elasticse ...
- arcgis api for js自定义引用方式
(1)常规模式 即arcgis js常见的模块引用方式,采用 require-function 模式,function的参数与require一一对应即可(dojo/domReady!比较特殊,无需 ...
- MicroK8S 安装 修改IP 设置镜像加速 升级 卸载等
系统要求: Ubuntu 20.04 LTS, 18.04 LTS or 16.04 LTS或其他支持snapd的操作系统 内存:4G+ 硬盘:20G+ 官方文档 安装microk8s sudo sn ...
- Mysql配置文件 基本设置
[mysqld] #MySQL启动用户 user = mysql #设置mysql的安装目录 basedir=/usr/local/mysql #mysql.sock存放目录 socket=/var/ ...
- Git忽略提交规则 .gitignore文件
在使用Git的过程中,我们喜欢有的文件比如日志,临时文件,编译的中间文件等不要提交到代码仓库,这时就要设置相应的忽略规则,来忽略这些文件的提交.简单来说一个场景:在你使用git add .的时候,遇到 ...
- apt和apt-get的区别
目录 一.简介 二.apt vs apt-get 为什么apt首先被引入? apt和apt-get之间的区别 apt和apt-get命令之间的区别 我应该使用apt还是apt-get? 三.结论 一. ...
- ubuntu 16.04下的fastadmin安装指南
此篇博客转载于fastadmin论坛,方便自己看转到了博客里 说明文档不多,特制作一个,方便大家交流使用Ubuntu 16.04 安装fastadmin指南本文因考虑到大多数人员,习惯性在window ...