RabbitMQ 笔记
来源:互联网 发布:wifi模块远程控制源码 编辑:程序博客网 时间:2024/05/29 05:56
本文出自于EumJi个人博客,仅限于学习用途的转载,转载请注明出处http://www.eumji025.com/article/details/256524
前言
本部分专题是个人学习RabbitMQ的笔记,本篇介绍RabbitMQ的基本概念和使用RabbitMQ实现一个简单的消息队列例子.
本文不介绍安装配置,自行百度.
简介
RabbitMQ是一套开源(MPL)的消息队列服务软件,是由 LShift 提供的一个 Advanced Message Queuing Protocol (AMQP) 的开源实现,由以高性能、健壮以及可伸缩性出名的 Erlang 写成。
–摘自维基百科
RabbitMQ作为消息队列,可以接受 并转发消息。您可以把他理解为邮局:将您需要发布的消息放在这个中间件中,最终会被发送给接受方。这些概念比较基础使用过多线程也应该非常熟悉。有点类似生产者和消费者模式,在此就不进行过多的描述。
Rabbit 术语介绍
生产者
生产者往往指的是消息的发送方,在程序中则主要是指发送消息的那部分片段。
队列
队列主要是用来存放生产者推送过来的消息,等待消费者提取消息的中间件。类似于邮局这类中间成员。
这是RabbitMQ的核心部分
消费者
消费者是和上面描述的生产者对立的,主要是消息的接受方。
JAVA演示
RabbitMQ支持多种编程语言(java,python,ruby,C#,PHP。。。),具体参见官方文档。这里主要演示JAVA中的RabbitMQ hello world示例。
环境准备
1.使用java项目需要下载RabbitMQ相关的jar
核心: amqp-client-4.0.2.jar
RabbitMQ的client还依赖slf4j的jar包
依赖: slf4j-api-1.7.21.jar
slf4j-simple-1.7.21.jar(缺少此jar无法正确输出)
2.使用maven项目需要如下主要依赖
<!-- https://mvnrepository.com/artifact/com.RabbitMQ/amqp-client --> <dependency> <groupId>com.RabbitMQ</groupId> <artifactId>amqp-client</artifactId> <version>4.1.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-simple --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.21</version> </dependency>
项目结构图
生产者代码
public class Product { private static Logger logger = LoggerFactory.getLogger(Product.class); public static final String QUEUE_HELLO = "FIRST_QUEUE"; public static void main(String[] args) { //1.创建连接工厂 ConnectionFactory factory = new ConnectionFactory(); //2.配置工厂的RabbitMQ server的主机 factory.setHost("localhost"); Connection connection = null; Channel channel = null; try { //3.新建一个连接 connection = factory.newConnection(); //4.获取一个连接频道 channel = connection.createChannel(); /** * 5.配置一个队列的信息 * 在RabbitMQ中,队列声明是幂等性的(一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同) * 也就是说,如果不存在,就创建,如果存在,不会对已经存在的队列产生任何影响。 * @param queue 队列名称 * @param durable 如果我们声明持久队列(队列将在服务器重新启动后生效),则为true * @param exclusive 如果我们声明排他队列(限于此连接),则为true * @param autoDelete 如果我们声明一个自动删除队列,则为true(服务器将在不再使用时将其删除) * @param arguments 队列的其他属性(构造参数) */ channel.queueDeclare(QUEUE_HELLO,false,false,false,null); String message = "Hello World!" ; /** * 6.将消息放在队列中(字节数组形式) * @param exchange 交换发布消息 * @param routingKey 路由密钥 * @param props 消息的其他属性 - 路由头等 * @param body 消息体 */ channel.basicPublish("",QUEUE_HELLO,null,message.getBytes()); System.out.println("product Sent '" + message + "'"); } catch (IOException e) { logger.error("RabbitMQ发送消息发生IO异常"); e.printStackTrace(); } catch (TimeoutException e) { logger.error("RabbitMQ发生连接超时异常"); e.printStackTrace(); }finally { try { //7.关闭连接 channel.close(); connection.close(); } catch (IOException e) { logger.error("RabbitMQ关闭发生IO异常"); e.printStackTrace(); } catch (TimeoutException e) { logger.error("RabbitMQ发生关闭超时异常"); e.printStackTrace(); } } }
主要操作步骤在代码中都有注明,有点类似hibernate的操作。理解起来相对简单。只要注意 channel.queueDeclare(QUEUE_HELLO,false,false,false,null)不会每次都新建一个队列,而是先去查询是否存在,若存在则不进行操作。
消费者代码
public class Customer { private static Logger logger = LoggerFactory.getLogger(Product.class); public static final String QUEUE_HELLO = "FIRST_QUEUE"; public static void main(String[] args) { //1.创建连接工厂 ConnectionFactory factory = new ConnectionFactory(); //2.配置工厂的RabbitMQ server的主机 factory.setHost("localhost"); Connection connection = null; Channel channel = null; try { //3.新建一个连接 connection = factory.newConnection(); //4.获取一个连接频道 channel = connection.createChannel(); /** * 5.声明队列的信息 * 在RabbitMQ中,队列声明是幂等性的(一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同) * 也就是说,如果不存在,就创建,如果存在,不会对已经存在的队列产生任何影响。 * @param queue 队列名称 * @param durable 如果我们声明持久队列(队列将在服务器重新启动后生效),则为true * @param exclusive 如果我们声明排他队列(限于此连接),则为true * @param autoDelete 如果我们声明一个自动删除队列,则为true(服务器将在不再使用时将其删除) * @param arguments 队列的其他属性(构造参数) */ channel.queueDeclare(QUEUE_HELLO,false,false,false,null); System.out.println("customer wait message!!!"); //覆盖DefaultConsumer的handleDelivery方法,回调信息 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,0,body.length,"UTF-8"); System.out.println(message); logger.info("收到productor的消息:"+message); } }; channel.basicConsume(QUEUE_HELLO,true,consumer); } catch (IOException e) { logger.error("RabbitMQ发送消息发生IO异常"); e.printStackTrace(); } catch (TimeoutException e) { logger.error("RabbitMQ发生连接超时异常"); e.printStackTrace(); } }}
消费者的代码和生产者的步骤类似,只是消费者不推送消息,而是去获取消息,需要覆盖DefaultConsumer的handleDelivery方法,进行自己的消息处理。
消费者不要关闭连接,不然将不会进行轮询,直接查询一次后就结束。
演示
首先我们启动是消费者,此时没有消息的推送,消费者等待消息,输出如下:
customer wait message!!!
然后启动生产者,生产者输出如下:
product Sent 'Hello World!'
然后再查看消费者的控制台,结果如下:
Hello World![pool-1-thread-4] INFO com.eumji.RabbitMQ.Product - 收到productor的消息:Hello World!
RabbitMQ server
经过上面的测试后我们可以在本地RabbitMQ server中查看相关信息 http://localhost:15672/#/
最后说两句
RabbitMQ的入门例子和多线程中的生产者消费者很类似,大家有兴趣可以去了解一下。
本文原文出自于http://www.rabbitmq.com/tutorials/tutorial-one-java.html
对官方的教程进行部分翻译和修改!!!
与君共勉!!!
参考资料
RabbitMQ官方文档
个人源码
RabbitMQ-helloworld
- RabbitMQ笔记
- rabbitmq 笔记
- rabbitmq笔记
- rabbitmq笔记
- RabbitMQ 笔记
- RabbitMQ 笔记
- RabbitMQ 笔记
- RabbitMQ笔记
- RabbitMQ 学习笔记
- RabbitMQ概念笔记
- rabbitmq学习笔记一
- RabbitMQ使用笔记
- RabbitMQ学习笔记
- Rabbitmq学习笔记
- RabbitMQ学习笔记
- RabbitMQ 使用笔记
- rabbitmq学习笔记
- RabbitMQ学习笔记
- Java Spring mvc 操作 Redis 及 Redis 集群
- Log4j的配置与使用
- CodeFroces 812A Sagheer and Crossroads
- 案例解析逆向思维SEO技巧
- 【C-Coding】cJSON使用以及在stm32中的应用
- RabbitMQ 笔记
- 计算具体某天是星期几
- 前端学习笔记2-CSS
- 《数学之美》阅读笔记part1——第1章到第15章
- 浅谈Spring事务隔离级别
- 【centos】php5.4升级到php5.6
- Linux 参看cuda 及 显卡
- 安卓中的线程
- Android 使用Rtmp音视频推流