RabbitMQ
什么是RabbitMQ?
RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现。AMQP 的出现其实也是应了广大人民群众的需求,虽然在同步消息通讯的世界里有很多公开标准(如 COBAR的 IIOP ,或者是 SOAP 等),但是在异步消息处理中却不是这样,只有大企业有一些商业实现(如微软的 MSMQ ,IBM 的 Websphere MQ 等),因此,在 2006 年的 6 月,Cisco 、Redhat、iMatix 等联合制定了 AMQP 的公开标准。
RabbitMQ是由RabbitMQ Technologies Ltd开发并且提供商业支持的。该公司在2010年4月被SpringSource(VMWare的一个部门)收购。在2013年5月被并入Pivotal。其实VMWare,Pivotal和EMC本质上是一家的。不同的是VMWare是独立上市子公司,而Pivotal是整合了EMC的某些资源,现在并没有上市。
RabbitMQ官网:http://www.rabbitmq.com/
RabbitMQ的优点
1.同步变异步
可以使用线程池解决,但是缺点很明显:要自己实现线程池,并且强耦合
大多数是使用消息队列来解决
2.低内聚高耦合:解耦----减少强依赖.
3.流量削峰---秒杀系统
通过消息队列设置请求最大值,超过阀值的抛弃或者转到错误界面.
4.rabbitmq采用信道通信。不采用tcp直接通信
1).tcp的创建和销毁开销大,创建3次握手,销毁4四次分手
2).高峰时成千上万条的链接会造成资源的巨大浪费,而且操作系统没秒处理tcp的数量也是有数量限制的,必定造成性能瓶颈
3).一条线程一条信道,多条线程多条信道,公用一个tcp连接。一条tcp连接可以容纳无限条信道(硬盘容量足够的话),不会造成性能瓶颈。
MQ的作用:
解耦:在项目启动之初是很难预测未来会遇到什么困难的,消息中间件在处理过程中插入了一个隐含的,基于数据的接口层,两边都实现这个接口,这样就允许独立的修改或者扩展两边的处理过程,只要两边遵守相同的接口约束即可。
冗余(存储):在某些情况下处理数据的过程中会失败,消息中间件允许把数据持久化知道他们完全被处理
扩展性:消息中间件解耦了应用的过程,所以提供消息入队和处理的效率是很容易的,只需要增加处理流程就可以了。
削峰:在访问量剧增的情况下,但是应用仍然需要发挥作用,但是这样的突发流量并不常见。而使用消息中间件采用队列的形式可以减少突发访问压力,不会因为突发的超时负荷要求而崩溃
可恢复性:当系统一部分组件失效时,不会影响到整个系统。消息中间件降低了进程间的耦合性,当一个处理消息的进程挂掉后,加入消息中间件的消息仍然可以在系统恢复后重新处理
顺序保证:在大多数场景下,处理数据的顺序也很重要,大部分消息中间件支持一定的顺序性
缓冲:消息中间件通过一个缓冲层来帮助任务最高效率的执行
异步通信:通过把把消息发送给消息中间件,消息中间件并不立即处理它,后续在慢慢处理。
RabbitMQ:
它是采用Erlang语言实现的AMQP(Advanced Message Queued Protocol)的消息中间件,最初起源于金融系统,用在分布式系统存储转发消息。
RabbitMQ发展到今天,被越来越多的人认可,这和它在易用性、扩展性、可靠性和高可用性等方面的卓著表现是分不开的。RabbitMQ的具体特点可以概括为以下几点:
可靠性:RabbitMQ使用一些机制来保证可靠性,如持久化、传输确认及发布确认等。
灵活的路由:在消息进入队列之前,通过交换器来路由消息。对于典型的路由功能,RabbitMQ己经提供了一些内置的交换器来实现。针对更复杂的路由功能,可以将多个交换器绑定在一起,也可以通过插件机制来实现自己的交换器。
扩展性:多个RabbitMQ节点可以组成一个集群,也可以根据实际业务情况动态地扩展集群中节点。
高可用性:队列可以在集群中的机器上设置镜像,使得在部分节点出现问题的情况下队仍然可用。
多种协议:RabbitMQ除了原生支持AMQP协议,还支持STOMP,MQTT等多种消息中间件协议。
多语言客户端:RabbitMQ几乎支持所有常用语言,比如Jav a、Python、Ruby、PHP、C#、JavaScript等。
管理界面:RabbitMQ提供了一个易用的用户界面,使得用户可以监控和管理消息、集群中的节点等。
插件机制:RabbitMQ提供了许多插件,以实现从多方面进行扩展,当然也可以编写自己的插件。
RabbitMQ 选型和对比
1.从社区活跃度
按照目前网络上的资料,RabbitMQ 、activeM 、ZeroMQ 三者中,综合来看,RabbitMQ 是首选。
2.持久化消息比较
ZeroMq 不支持,ActiveMq 和RabbitMq 都支持。持久化消息主要是指我们机器在不可抗力因素等情况下挂掉了,消息不会丢失的机制。
3.综合技术实现
可靠性、灵活的路由、集群、事务、高可用的队列、消息排序、问题追踪、可视化管理工具、插件系统等等。
RabbitMq / Kafka 最好,ActiveMq 次之,ZeroMq 最差。当然ZeroMq 也可以做到,不过自己必须手动写代码实现,代码量不小。尤其是可靠性中的:持久性、投递确认、发布者证实和高可用性。
4.高并发
毋庸置疑,RabbitMQ 最高,原因是它的实现语言是天生具备高并发高可用的erlang 语言。
5.比较关注的比较, RabbitMQ 和 Kafka
RabbitMq 比Kafka 成熟,在可用性上,稳定性上,可靠性上, RabbitMq 胜于 Kafka (理论上)。
另外,Kafka 的定位主要在日志等方面, 因为Kafka 设计的初衷就是处理日志的,可以看做是一个日志(消息)系统一个重要组件,针对性很强,所以 如果业务方面还是建议选择 RabbitMq 。
还有就是,Kafka 的性能(吞吐量、TPS )比RabbitMq 要高出来很多。
选型最后总结:
如果我们系统中已经有选择 Kafka ,或者 RabbitMq ,并且完全可以满足现在的业务,建议就不用重复去增加和造轮子。
可以在 Kafka 和 RabbitMq 中选择一个适合自己团队和业务的,这个才是最重要的。但是毋庸置疑现阶段,综合考虑没有第三选择。
服务端安装和配置
客户端示例代码
NuGet安装:
Install-Package RabbitMQ.Client
RabbitMQ使用过程介绍
1、连接远程服务器失败问题
解决方法:
默认的guest用户是禁止远程连接的,它只能通过localhost连接本地服务。可以通过可视化管理界面,添加一个用户和密码,设置相应的管理员权限,使用新的用户可以远程连接服务。
官网也有提到修改配置文件,但未测试成功。
2、有关官网几种示例运行测试结果介绍
1)Simplest
运行效果说明:
a)无论生产者和消费者哪一个先开启,都可接收和发送简单消息(监听的是同一个名称的queue);
b)声明一个queue时,属性durable设置成true,该队列持久化,即RabbitMQ服务崩溃时,消息不会丢失,但持久化会对RabbitMQ的性能造成比较大的影响,可能会下降10倍不止。
2)WorkQueues
运行效果说明: a)无论生产者和消费者哪个先开启,都可以接收到消息;
b)若开启一个生产者,多个消费者,如果queue中存在耗时任务时,会将新的消息任务发送给其他消费者;
3)Publish/Subscribe
a)必须先运行消费者代码,再开启生产者发送消息,消费者才可以接收到消息;
b)一个生产者、多个消费者时,发送一条消息可被多个生产者接收;
4)Routing
a)必须先运行消费者代码,再开启生产者发送消息,消费者才可以接收到消息;
b)生产者和消费者约定好消息类型,消费者可只接收指定类型的消息;
5)Topics
a)必须先运行消费者代码,再开启生产者发送消息,消费者才可以接收到消息;
b)消费者可以接收一类消息,可接收所有满足模式匹配类型的消息,
例如:“*.info”意味着可以接收以任意一个单词+“.info”结尾的类型消息;
一个*代表一个单词,多个单词时可写成“*.*.info”;
“#”代表零个或者多个,可写成“#.info”。
6)RPC(Remote Procedure Call)
a)服务端先开启才可接收客户端的请求;
b)客户端发送请求到服务端,服务端将处理结果或其他消息发送到客户端(即是通知客户端此次请求已完成相关处理操作);
c)客户端发多条请求时,如果有一条请求处理的时间较长,服务端会一直等待处理结束才会处理下一条请求内容;
备注: 1、Publish/Subscribe、Routing、Topics三种方式都需要先开消费者,具体流程消费者声明一个exchange,并且自动用随机名称生成临时queue,绑定监听queue上的消息(消费者停止后,临时queue会自动销毁);
2、采用生产者先将消息发送到exchange上,exchange会遍历找到所有绑定它的queue,然后把消息发送到queue中,消费者可收到queue上的消息;
3、这三种方式属于广播性质,具有实时性,消费者开启时,生产者发消息就可以接收,未开启就不接收;
4、声明的exchange不会自动销毁;
参考资料
- 官网:http://www.rabbitmq.com/
- RabbitMQ中文文档 · RabbitMQ in Chinese
- 官方示例代码
- RabbitMQ中 exchange、route、queue的关系:https://www.cnblogs.com/linkenpark/p/5393666.html
- 参考文献:《RabbitMQ实战指南》(本书示例使用Java,但理论部分可以作为参考)