前言
RabbitMQ 和很多消息中间件技术一样,主要是为了解决分布式架构系统中系统和系统之间的通讯问题
RabbitMQ 是基于 AMQP 协议进行通讯的,AMQP协议是在 TCP/IP协议之上的协议。为什么不使用 HTTP 协议,是因为 HTTP 协议相对而言太过复杂,有cookie,加密,等等一系列信息,传输效率比较低,并且 大部分情况下,HTTP协议都是短连接,无法保证数据的完整和不具有持久化的功能。所以RabbitMQ就制定了自己的一套协议,AMQP协议。
RabbitMQ 是基于channel 通道处理,不是基于连接,因为连接开关是短连接,并且耗时长,经过三次握手四次挥手
如何保证消费者可靠的消费消息,用ack机制,手动消费nack完成
RabbitMQ 可以存在没有交换机的队列么,不能,虽然没有指定交换机,但是会存在一个默认的交换机,消息都是通过交换机传递给队列的
虚拟机节点主要是用于隔离和区分
优缺点
1、避免系统底层复杂性即解耦:优点很明显,因为 RabbitMQ 是用来处理系统之间的通讯的,所以是避免了系统底层的复杂性,使系统的可拓展性更强,只需要遵循 AMQP 协议,系统无论是使用Java还是PHP还是其它语言开发,都可以互相通讯。
2、削峰:例如在当一个系统在其它时间段每秒都只有几百的数据请求,这个时候数据等压力都很小,当中午时间段请求突然增大增加到六千每秒的请求,这个时候RabbitMQ作用就起到的很大的作用
3、持久化:当RabbitMQ宕机前,消息都会持久化。
4、高可用、高并发:支持分布式,支持并发请求。
对比
除了 RabbitMQ 消息中间件还有很多其它类似的中间件技术例如 ActiveMQ,RocketMQ,Kafka 等。相比于其它消息中间件,RabbitMQ 优势在于他的消息分发机制完善,支持消息的订阅分发,公平分发,轮训分发,重发和消息的拉取等机制。RabbitMQ底层是使用 erlang 语言编写的,而erlang底层是 C 语言编写的,所以RabbitMQ的性能和并发能力很强。Kafka是基于Java 编写的,使用的是 Kafka 通讯协议,是给予 TCP/IP 协议上进行的,直接将通讯连接和数据转化为二进制,性能很强。但是在分布式架构中,最大的痛点就是不支持事务,所以一般Kafka在大数据领域中使用广泛,专门用来处理数据的分发。
扩展
Redis 也是一款性能极强的消息中间件,而且也具有数据持久化的功能,但是为什么还需要有 RabbitMQ 等其它消息中间件。
因为 Redis 的持久化有两种方式,一个是 RDB(Redis DataBase) 一个是 AOF(append only file),RDB 持久化可以在指定的时间间隔内生成数据集的快照,AOF 是通过记录服务器所有写操作命令,并再服务器启动时,通过重新执行这些命令来还原数据集。
缺点是 RDB 的时间差会导致很多数据的丢失,AOF一般文件大于RDB,而且可能会出现无法将数据集恢复成原来的样子的问题。
消息分发策略
消息机制 ActiveMQ RabbitMQ Kafka RocketMQ 发布订阅 支持 支持 支持 支持 轮询分发 支持 支持 支持 / 公平分发 / 支持 支持 / 重发 支持 支持 / 支持 消息拉取 / 支持 支持 支持
发布订阅:生产者产生100条消息,每个消费者都会收到100条消息
轮询分发:假如生产者产生100条消息,如果有三个消费者,可能消费的顺序不固定,但是最终每个消费者至少都会消费 33 条消息,不会产生数据倾斜,使用RabbitMQ的自动应答就可以实现。
公平分发:根据消费的服务器的性能来进行消息的分发,会产生数据倾斜,而且必须进行手动应答。和轮询分发一样,一个消息不会被第二次消费。
重发:顾名思义,在分布式系统中,如果有多个订单系统,如果创建订单的消息分发给其中一个系统失败,会分发给其它系统。
消息拉取:消费者主动拉取,但是一般很少用到。
高可用和高可靠
高可用
所谓高可用就是指产品在规定的条件和规定的时刻或时间内处于可执行规定功能状态和能力。当业务量增加时,请求也过大,一台消息中间件服务器会触及硬件(CPU,内存,磁盘)的极限,一台消息服务器已经无法满足业务的需求,所以消息中间件必须支持集群部署来达到高可用目的。
所有的集群模式,终归三句话
要么消息共享
要么消息同步
要么元数据共享
高可靠
所谓高可靠就是指,系统可以无故障低持续运行,比如一个系统突然奔溃,报错,异常等并不影响线上业务的正常运行,出错的几率基地,称之为可靠。
再高并发的业务场景中,如果不能保证系统的高可靠,那造成的隐患和损失是非常严重的。
如何保证中间消息的可靠性?从两个方面考虑
1:消息的传输:通过洗衣来保证系统间数据解析的正确性
2:消息的存储可靠:通过持久化来保证消息的可靠性。