RabbitMQ,最近接触到RabbitMQ的监控,稍稍了解了一下其原理,做了队列监控和集群状态监控,特此记录下来。
讲RabbitMQ之前先介绍下MQ吧。MQ全称Message Queue,消息队列,顾名思义,由一条一条消息组成的一个队列,专业术语说就是一种跨进程的通信机制。如此一来,进程和进程之间就可以不用互相调用来进行通信了,换句话说,MQ负责两个系统之间的消息传递
为什么要用MQ呢?最主要的三个应用场景用6字概括:解耦、异步、削峰
1、解耦:将消息写入消息队列,需要消息的时候自己从消息队列中订阅,从而原系统不需要做任何修改。换句话就是进程之间不用相互调用了。
2、异步:将消息写入消息队列,非必要的业务逻辑以异步的方式运行,加快响应速度。
3、削峰:原系统慢慢的按照数据库能处理的并发量,从消息队列中慢慢拉取消息。在生产中,这个短暂的高峰期积压是允许的。可以很大程度上避免大量请求同时请求数据库造成数据库连接异常的情况。
当然还有其他的场景,比如冗余、扩展性、过载保护、可恢复性、顺序保证、缓冲、数据流处理等等。
当然,MQ也不是十全十美的,也有其自身的缺点,大致如下:
1、系统的可用性降低了,如果MQ挂了,那么系统之间的运作固然会受到影响
2、增加了系统的复杂性,需要考虑到如何保证消息不被重复消费,如何保证消息可靠传输,所以说增加了复杂性
一个合适的MQ最后能达到以下几点,1、全天不宕机2、100%数据不会丢失3、读写高效4、监控工具完善。
目前常见的产品有RabbitMQ、ZeroMQ、ActiveMQ、Kafka、RocketMQ(阿里巴巴的)等。
那么如何选择用哪一款MQ呢? ActiveMQ和RabbitMQ的吞吐量是万级,而RocketMQ和kafka是十万级,前两个是主从式架构,而后两者是分布式架构,显然分布式的可用性要高于主从架构。大概比较见下图
特性 |
ActiveMQ |
RabbitMQ |
RocketMQ |
kafka |
语言 |
Java |
Erlang |
Java |
scala |
单机吞吐量 |
万级 |
万级 |
十万级 |
十万级 |
时效性 |
ms |
us |
ms |
ms以内 |
架构 |
主从架构 |
主从架构 |
分布式架构 |
分布式架构 |
功能特性 |
产品成熟,有较多文档, |
基于erlang可开发,并发能力强,延时极低,性能极好 |
MQ功能比较完备,扩展性佳 |
只支持主要的MQ功能,比如消息查询等,没有消息回溯等功能,在大数据领域应用广泛 |
正所谓依照国情办事,最好的并不一定就是最合适的,综合起来大致如下
1、中小型软件公司, RabbitMQ可能会更合适, 一方面没有那么大的数据量,其次主从架构的资源消耗低于分布式架构,没必要上分布式的,再者rabbit功能比较完备,所以kafka排除,RocketMQ是阿里的东西,如果阿里放弃维护,还需要一部分人来进行定制化开发。
2、大型软件公司,选择RocketMQ还是kafka视情况而定,大型公司有足够的资金搭建分布式环境,也有足够大的数据量。
说了那么多,现在正式开始讲RabbitMQ,,先介绍几个名词:
ConnectionFactory(连接管理器):应用程序与Rabbit之间建立连接的管理器,程序代码中使用;
Connection():就是一个TCP的连接,Producer和Consumer都是通过TCP连接到RabbitMQ Server的
Producer(生产者):消息的生产发布者
Consumer(消费者):获取消息进行处理者
Channel(信道):消息推送使用的通道;数据流动都是在Channel中进行的。也就是说,一般情况是程序起始建立TCP连接,第二步就是建立这个Channel。
Exchange(交换器):用于接受、分配消息;
Queue(队列):用于存储生产者的消息;多个消费者可以监听同一个Queue,Queue中的消息会被平均分配给多个消费者,但是并不能控制哪条消息给哪个消费者,也不是说每个消费者都收到所有的消息并进行处理,
RoutingKey(路由键):用于把生成者的数据分配到交换器上;
BindingKey(绑定键):用于把交换器的消息绑定到队列上;
RabbitMQ中如下方式运作
如果上图不够直观,下图可以更好的理解流程
再概化一下流程如下
企业用RabbitMQ当然不会是单一的使用,必然会上集群,其有四种集群架构,分别是1、主备模式2、远程模式3、镜像模式4、多活模式。
1、主备模式
一般在并发和数据量不高的情况下,这种模式非常的好用且简单。和其他的主备模式一样,一个主节点一个或多个备节点,主节点能进行读写,备用节点不能读写,当主节点挂了,切换到备用节点,此时备用节点升级为主节点,能进行读写,此时挂了的旧主节点如果恢复,就会变成新的备用节点,架构如下图(图片来自网络)
2、远程模式
其实就是一个双活模式,把消息在不同的MQ中心进行一个复制,让两个MQ集群互相联通,进行远距离通信和复制原理图大致如下(图片从网络获取)
3、镜像模式
这是很多很多高可用都用到的经典mirror镜像模式,能保证100%数据不丢失,实现也非常之简单,是许多大厂的不二之选
消息从app发出到主节点上之后,主节点通过mirror队列同步到其他MQ节点上,一般采用三个节点的集群,大致流程图如下(图片来自网络)
4、多活模式
也是实现异地数据复制的主流模式,因为远程模式配置比较复杂,所以一般来说,实现异地集群的都是采用这种双活 或者 多活模型来实现的。这种模式需要依赖 rabbitMQ 的 federation 插件,可以实现持续的,可靠的 AMQP 数据通信,多活模式在实际配置与应用非常的简单。
rabbitMQ 部署架构采用双中心模式(多中心),那么在两套(或多套)数据中心各部署一套 rabbitMQ 集群,各中心的rabbitMQ 服务除了需要为业务提供正常的消息服务外,中心之间还需要实现部分队列消息共享。架构如下图(来自网络)
看到这里想必大概的流程应该明白了,但还有许许多多的小问题,请移步关于RabbitMQ的一些思考