消息中间件的介绍与比较
一. 消息中间件的概述
消息队列(英语:Message queue)是一种进程间通信或同一进程的不同线程间的通信方式,软件的贮列用来处理一系列的输入,通常是来自用户。消息队列提供了异步的通信协议,每一个贮列中的纪录包含详细说明的数据,包含发生的时间,输入设备的种类,以及特定的输入参数,也就是说:消息的发送者和接收者不需要同时与消息队列互交。消息会保存在队列中,直到接收者取回它。
消息队列成为了异步RPC的主要手段之一
二. 消息中间件的组成
2.1 Broker
消息服务器,作为server提供消息核心服务。
2.2 Producer
消息生产者、业务的发起方、负责生产消息传输给broker
2.3 Consumer
消息消费者、业务的处理方,负责从broker获取消息并进行业务逻辑处理
2.4 Topic
主题,发布订阅模式下的消息统一汇聚地,不同生产者向topic发送消息,由MQ服务器分发到不同的订阅者,实现消息的通信
2.5 Queue
队列,PTP模式下,特定生产者向特定的queue发送消息,消费订阅特定的queue完成指定消息的接收
2.6 Message
消息体,根据不同通信协议定义的固定格式进行编码的数据包,来封装业务数据,实现消息的传输
三. 消息中间件的模式分类
3.1 点对点模式
PTP点对点:使用queue作为通讯载体
消息生产者生产消息发送到queue,然后消费消费者从queue中取出并且消费消息。
消息被消费以后,queue中不会存储,所以消息消费者不可能消费到已经被消费的消息,Queue支持存在多个消费者或者多个生产者
3.2 发布/订阅模式
Pub/Sub发布订阅(广播):使用topic作为通信载体
消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息。和点对点方式不同,发布到topic的消息会被所有订阅者消费。
queue实现了负载均衡,将producer生产的消息发送到消息队列中,由多个消费者消费。但一个消息只能被一个消费者接受,当没有消费者可用时,这个消息会被保存直到有一个可用的消费者。
topic实现了发布和订阅,当你发布一个消息,所有订阅这个topic的服务都能得到这个消息,所以从1到N个订阅者都能得到一个消息的拷贝。
四. 消息中间件的优点
4.1 解耦
系统A要发送一个消息到多个系统,如果此时每增加一个系统,系统A都需要通过修改源码来增加接口,此时耦合非常高,但是如果中间使用消息队列的话,系统只需要发送一次到消息队列,别的系统就能复用该信息,当增加或删除系统调用接口的时候,不需要额外的更新代码。
4.2 异步
用户调用一个接口的时候,可能该接口调用了别的方法。例如:用户注册的时候,后台可能需要调用:查询数据库,插入数据库,发送邮件,发送用户指南等等...
但是用户可能并不需要后台将所有的任务执行完毕,那么此时在初入数据口后面加入mq队列,用户就能很快得到注册成功的响应而去做一些别的事情。mq的机制又能保证最终的一致性,所以使用起来很安全很稳定。
4.3 削峰
何为消峰,就是当系统压力过大的时候,让系统压力减小。如何做?
加入数据库的读写每秒3000,在高峰期,系统的访问达到了每秒10000。此时由于加入了消息队列,所以不会出现激增的访问导致系统奔溃。 (注意,削峰并不会让用户的等待时间减少,所以一般会跟异步搭配来使用)
五. 常用消息中间件MQ说明
5.1 ActiveMQ(基本被淘汰)
ActiveMQ是Apache下的一个子项目,它能够以代理人和点对点的技术实现队列,它少量代码就可以高效的实现高级应用场景。
会丢失消息、并发量并不高
非常成熟,功能强大,在业内大量的公司以及项目中都有应用偶尔会有较低概率丢失消息而且现在社区以及国内应用都越来越少,官方社区现在对ActiveMQ 5.x维护越来越少,几个月才发布一个版本而且确实主要是基于解耦和异步来用的,较少在大规模吞吐的场景中使用
5. 2 RabbitMQ
erlang语言开发,性能极其好,延时很低;吞吐量到万级,MQ功能比较完备而且开源提供的管理界面非常棒,用起来很好用社区相对比较活的。RabbitMQ吞吐量会低一些,这是因为他做的实现机制比较重。erlang开发很难去看懂源码,你公司对这个东西的掌控很弱,基本职能依赖于开源社区的快速维护和修复bug。
5.3 kafka
10万级别,这是kafka最大的优点,就是吞吐量高。一般配合大数据类的系统来进行实时数据计算、日志采集等场景。kafka的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展同时kafka最好是支撑较少的topic数量即可,保证其超高吞吐量而且kafka唯一的一点劣势是有可能消息重复
5.4 RocketMQ
10万级,RocketMQ也是可以支撑高吞吐的一种MQ。接口简单易用,而且毕竟在阿里大规模应用过,可以做到大规模吞吐,性能也非常好,分布式扩展也很方便,社区维护还可以,可靠性和可用性是ok的,还可以支撑大规模的topic数量。阿里出品都是java系的,我们可以自己阅读源码。
以上四种消息中间件的比较
特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
---|---|---|---|---|
单机吞吐量 | 万级,吞吐量比RocketMQ和Kafka要低了一个数量级 | 万级,吞吐量比RocketMQ和Kafka要低了一个数量级 | 10万级,RocketMQ也是可以支撑高吞吐的一种MQ | 10万级别,这是kafka最大的优点,就是吞吐量高。一般配合大数据类的系统来进行实时数据计算、日志采集等场景 |
topic数量对吞吐量的影响 | topic可以达到几百,几千个的级别,吞吐量会有较小幅度的下降这是RocketMQ的一大优势,在同等机器下,可 | topic可以达到几百,几千个的级别,吞吐量会有较小幅度的下降这是RocketMQ的一大优势,在同等机器下,可 | ||
时效性 | ms级 | 微秒级,这是rabbitmq的一大特点,延迟是最低的 | ms级 | 延迟在ms级以内 |
可用性 | 高,基于主从架构实现高可用性 | 高,基于主从架构实现高可用性 | 非常高,分布式架构 | 非常高,kafka是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用 |
消息可靠性 | 有较低的概率丢失数据 | 经过参数优化配置,可以做到0丢失 | 经过参数优化配置,消息可以做到0丢失 | |
功能支持 | MQ领域的功能极其完备 | 基于erlang开发,所以并发能力很强,性能极其好,延时很低 | MQ功能较为完善,还是分布式的,扩展性好 | 功能较为简单,主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用,是事实上的标准 |
优劣势总结 | 非常成熟,功能强大,在业内大量的公司以及项目中都有应用偶尔会有较低概率丢失消息而且现在社区以及国内应用都越来越少,官方社区现在对ActiveMQ 5.x维护越来越少,几个月才发布一个版本而且确实主要是基于解耦和异步来用的,较少在大规模吞吐的场景中使用 | erlang语言开发,性能极其好,延时很低;吞吐量到万级,MQ功能比较完备而且开源提供的管理界面非常棒,用起来很好用社区相对比较活的。RabbitMQ吞吐量会低一些,这是因为他做的实现机制比较重。erlang开发很难去看懂源码,你公司对这个东西的掌控很弱,基本职能依赖于开源社区的快速维护和修复bug。 | 接口简单易用,而且毕竟在阿里大规模应用过,可以做到大规模吞吐,性能也非常好,分布式扩展也很方便,社区维护还可以,可靠性和可用性是ok的,还可以支撑大规模的topic数量。阿里出品都是java系的,我们可以自己阅读源码。 | kafka的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展同时kafka最好是支撑较少的topic数量即可,保证其超高吞吐量而且kafka唯一的一点劣势是有可能消息重复消 |