1.RabbitMQ概述
简介:
-
MQ全称为Message Queue,消息队列是应用程序和应用程序之间的通信方法;
-
RabbitMQ是开源的,实现了AMQP协议的,采用Erlang(面向并发编程语言)编写的,可复用的企业级消息系统;
-
AMQP(高级消息队列协议)是网络协议,是一个异步消息传递所使用应用层协议规范,为面向消息中间件设计,基于此协议的客户端与消息中间件可以无视消息来源传递消息,不受客户端、消息中间件、不同的开发语言环境等条件的限制;
-
支持主流操作系统:Linux、Windows,MacOX等;
-
支持多种客户端开发语言:Java、Python、Ruby、.NET,PHP、C/C++、Node.js等
术语说明:
-
Server(Broker):接收客户端连接,实现AMQP协议的消息队列和路由功能的进程;
-
Virtual Host:虚拟主机的概念,类似权限控制组,一个Virtual Host里可以有多个Exchange和Queue,权限控制的最小力度是Virtual Host;
-
Exchange:交换机,接收生产者发送的消息,并根据 Routing Key ;路由关键字,将消息路由到服务器中的队列Queue。
-
ExchangeType:交换机类型决定了路由消息行为,RabbitMQ中常用有三种类型Exchange,分别是fanout、direct、topic、(header);
-
Message Queue:消息队列,用于存储还未被消费者消费的消息;
-
Message:由Header和body组成,Header是由生产者添加的各种属性的集合,包括Message是否被持久化、优先级是多少、由哪个Message Queue接收等;body是真正需要发送的数据内容; BindingKey:绑定关键字,将一个特定的Exchange和一个特定的Queue绑定起来
上图:
-
RabbitMQ是基于AMQP(Advanced Message Queuting Protocol)
-
ActiveMQ、RocketMQ 是基于JMS 开发的
-
Kafka 是基于发布订阅开发的消息系统
这个图是关RabbitMQ的底层实现图,是完全根据AMQP的约定来开发的
什么是JMS:
查了很多博客,都讲的JMS是什么怎么用,都说他是J2EE的13个规范中的一个API,那我们从哪里取找它?更直观的认识他?
我在ActiveMQ的安装包中找到的
JMS底层架构图:
JMS即
Java消息服务(Java Message Service)应用程序接口,
是一个Java平台中关于面向消息中间件(MOM)的API,
用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持
《分布式消息中间件实践》中这样描述:JMS规范是对AMQP 、STOMP等消息通信协议的更高一层的抽象
JMS和AMQP的区别1 通信平台的区别JMS: 只允许基于JAVA实现的消息平台的之间进行通信AMQP: 允许多种消息协议进行通信,比如ruby的storm和java的jms都可以在AMQP上进行通信。结论: AMQP允许多种技术同时进行协议通信2 通信机制的区别JMS:消息生产者和消息消费者必须知道对方的QueueAMQP: 消息生产者和消息消费者无须知道对方的Queue,消息生产者将Exchange通过Route key和任意Queue绑定。消息消费者通过Route key从任意Queue中获取Exchange.3 消息传输机制的区别JMS:JMS支持PTP和publis/subscribe机制,PTP只可以点对点通信,public/subscribe在一端发出请求后所有其他端收到消息AMQP:1 所有RouteKey相同的Queue接受到数据2 所有相同的Exchange的Queue接受到数据3 所有wilecard的Exchange的Queue接受到数据4 可以让webservice等接受到数据
2.RabbitMQ安装启动与管理
2.1 Windows64位环境下安装RabbitMQ
到RabbitMQ官网下载win64位最新版erlang和rabbitmq-server的安装包,分别是 erlang otp_win64_19.3和rabbitmq-server-3.6.9。注意安装时计算机全名最好是英文,先安装erlang,再安装rabbitmq-server,根据安装向导,采用默认安装配置即可。安装完成后,可以从开始-所有程序中找到RabbitMQ Server如下图所示:
点RabbitMQ Command Prompt启动命令行,输入rabbitmq-plugins enable rabbitmq_management
启动管理工具,在浏览器中输入
http://127.0.0.1:15672/即可打开管理登录界面,默认超级管理员用户名guest,密码guest
2.2 Linux环境下安装RabbitMQ-----没有实操
先安装Erlang
rpm -Uvh erlang-solutions-1.0-1.noarch.rpm
sudo yum install erlang
再安装RabbitMQ
yum install rabbitmq-server-3.6.9-1.noarch.rpm
操作命令:
启动 service rabbitmq-server start
停止 service rabbitmq-server stop
重启 service rabbitmq-server restart
设置开机启动 chkconfig rabbitmq-server on
开启web界面管理工具
rabbitmq-plugins enable rabbitmq_management
service rabbitmq-server restart
防火墙开放15672端口访问
/sbin/iptables -I INPUT -p tcp --dport 15672 -j ACCEPT
/etc/rc.d/init.d/iptables save
2.3RabbitMQ管理界面添加用户和Virtual host
Admin-Users-Add a user
Add a user
Tags:用户角色说明
** 超级管理员(administrator)**
可登陆管理控制台,可查看所有的信息,并且可以对用户,策略(policy)进行操作。
监控者(monitoring)
可登陆管理控制台,同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)
策略制定者(policymaker)
可登陆管理控制台, 同时可以对policy进行管理,但无法查看节点的相关信息。
普通管理者(management)
仅可登陆管理控制台,无法看到节点信息,也无法对策略进行管理。
其他none
无法登陆管理控制台,通常就是普通的生产者和消费者。
Admin-Virtual Host-Add virtual host
Admin-Virtual Host
添加virtual host和用户后,需要为用户指定virtual host,之后用该用户可以登录
3.RabbitMQ的五种队列模式与实例
3.1 简单模式Hello World
简单模式Hello World
通用工具类:
创建连接工厂ConnectionFactory,设置服务地址127.0.0.1,端口号5672,设置用户名、密码、virtual host
功能:一个生产者P发送消息到队列Q,一个消费者C接收
生产者实现思路:
从连接工厂中获取连接connection,使用连接创建通道channel,使用通道channel创建队列queue,使用通道channel向队列中发送消息,关闭通道和连接。
消费者实现思路
创建消费者并监听队列,从队列中读取消息。
3.2 工作队列模式Work Queue
工作队列模式Work Queue
功能:一个生产者,多个消费者,每个消费者获取到的消息唯一,多个消费者只有一个队列
任务队列:避免立即做一个资源密集型任务,必须等待它完成,而是把这个任务安排到稍后再做。我们将任务封装为消息并将其发送给队列。后台运行的工作进程将弹出任务并最终执行作业。当有多个worker同时运行时,任务将在它们之间共享。
生产者实现思路:
创建连接工厂ConnectionFactory,设置服务地址127.0.0.1,端口号5672,设置用户名、密码、virtual host,从连接工厂中获取连接connection,使用连接创建通道channel,使用通道channel创建队列queue,使用通道channel向队列中发送消息,10条消息之间间隔一定时间,关闭通道和连接。
消费者实现思路:
创建消费者Recver1并监听队列,获取消息并暂停10ms,另外一个消费者Recver2暂停1000ms,由于消费者1消费速度快,所以2可以执行更多的任务。
结果:
3.3发布/订阅模式 Publish/Subscribe
发布/订阅模式 Publish/Subscribe
功能:一个生产者发送的消息会被多个消费者获取。一个生产者、一个交换机、多个队列、多个消费者
生产者:可以将消息发送到队列或者是交换机。
消费者:只能从队列中获取消息。
如果消息发送到没有队列绑定的交换机上,那么消息将丢失。
交换机不能存储消息,消息存储在队列中
生产者实现思路:
创建连接工厂ConnectionFactory,设置服务地址127.0.0.1,端口号5672,设置用户名、密码、virtual host,从连接工厂中获取连接connection,使用连接创建通道channel,使用通道channel创建队列queue,使用通道channel创建交换机并指定交换机类型为fanout,使用通道向交换机发送消息,关闭通道和连接。
消费者实现思路:
创建连接工厂ConnectionFactory,设置服务地址127.0.0.1,端口号5672,设置用户名、密码、virtual host,从连接工厂中获取连接connection,使用连接创建通道channel,使用通道channel创建队列queue,绑定队列到交换机,设置Qos=1,创建消费者并监听队列,使用手动方式返回完成。可以有多个队列绑定到交换机,多个消费者进行监听。
3.4路由模式Routing
路由模式Routing
说明:生产者发送消息到交换机并且要指定路由key,消费者将队列绑定到交换机时需要指定路由key
生产者实现思路:
创建连接工厂ConnectionFactory,设置服务地址127.0.0.1,端口号5672,设置用户名、密码、virtual host,从连接工厂中获取连接connection,使用连接创建通道channel,使用通道channel创建队列queue,使用通道channel创建交换机并指定交换机类型为direct,使用通道向交换机发送消息并指定key=a,关闭通道和连接。
消费者实现思路:
创建连接工厂ConnectionFactory,设置服务地址127.0.0.1,端口号5672,设置用户名、密码、virtual host,从连接工厂中获取连接connection,使用连接创建通道channel,使用通道channel创建队列queue,绑定队列到交换机,设置Qos=1,创建消费者并监听队列,使用手动方式返回完成。可以有多个队列绑定到交换机,但只要绑定key=a的队列key接收到消息,多个消费者进行监听。
3.5通配符模式Topic
通配符模式Topic
说明:生产者P发送消息到交换机X,type=topic,交换机根据绑定队列的routing key的值进行通配符匹配;
符号#:匹配一个或者多个词 lazy.# 可以匹配 lazy.irs或者lazy.irs.cor
符号*:只能匹配一个词 lazy.* 可以匹配 lazy.irs或者lazy.cor
生产者实现思路:使用通道channel创建交换机并指定交换机类型为topic,使用通道向交换机发送消息并指定key=key.1,关闭通道和连接。
消费者实现思路:
可以有多个队列绑定到交换机,凡是绑定规则符合通配符规则的队列均可以接收到消息,比如key.*,key.#,多个消费者进行监听。
解释一下routingKey 和bindingKey: 如图:key.xml就是RoutingKey,key.*就是BindingKey
4.Spring集成RabbitMQ配置
Spring提供了AMQP的一个实现,并且spring-rabbit是RabbitMQ的一个实现,下面给出订阅者模式的事例配置如下:
补充:消息可靠性的相关配置:
一、消息持久化机制
1、queue:
从exchange---->queue:保证在queue中
2、message:
在queue中的每个message保证持久化
3、exchange:
从消息生产端--->exchange: 保证在exchange可持久化的参数
但是从性能的角度,对于传送的消息全部写入磁盘效率无非是很低的,还可以有另外一个思路,监听消息响应,
来确定消息是否发送到了exchange,如果没有响应选择重新发送
二、消息确认模式-------发送方确认消息发送到Broker的解决方案
三、消费者确认模式------消息消费者的消费是成功还是失败的解决方案
1、消息回执模式
2、拒绝消息模式
3、消息预取模式
来解决有的消费者处理很快,出现资源空闲的情况,为了能做到能者多劳的情况,设置在一定范围内可以尽量多的处理消息:
5.总结
RabbitMQ提供6种模式,分别是Hello,Work Queue,Publish/Subscribe,Routing,Topics,RPC Request/reply,本文详细讲述了前5种,并给出代码实现和思路。
其中Publish/Subscribe,Routing,Topics三种模式可以统一归为Exchange模式,只是创建时交换机的类型不一样,分别是fanout、direct、topic。
Spring提供了rabbitmq的一个实现
注:根据该博客内容实践后,参考总结的作者:梁朋举
来源:oschina
链接:https://my.oschina.net/u/4321806/blog/4528153