MQ基础
1.消息中间件(MQ)
1.消息队列是什么?
消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削峰等问题 实现高可用 高性能 可伸缩和最终一致性架构。
能不要就不用,增加了系统的复杂度。
基于数据通信来进行分布式系统的集成,通过提供消息传递和消息排队模型,它可以在分布式环境下扩展进程间的通信,对于消息中间件,常见的角色大致也就有 Producer(生产者) 、 Consumer(消费者) 。
2.消息队列的特点
1.FIFO(先进先出)
先进先出是队列的一个特性不能先进先出,都不能说是队列了,消息队列的顺序在入队的时候就基本已经确定了,一般是不需要人工干预,最重要的是:数据是只有一条数据在使用中,这也是MQ在诸多场景被使用的原因
2.订阅
指的是MQ的广播模式,基于java的观察者模式
发布订阅是一种很高效的处理方式,如果不发生阻塞,基本可以当做是同步操作,这种处理方式能非常有效的提升服务器利用率。
3.持久化
持久化确保MQ的使用不只是一个部分场景的辅助工具,而是让MQ能像数据库一样存储核心的数据
4.分布式
在现在大流量、大数据的使用场景下,只支持单体应用的服务器软件基本是无法使用的,支持分布式的部署,才能被广泛使用,而且,MQ的定位就是一个高性能的中间件。
3.消息队列的通讯模式
1.点对点通讯点
点对点方式是最为传统和常见的通讯方式,它支持一对一、一对多、多对多、多对一等多种配置方式,支持树状、网状等多种拓扑结构,没有消费者组的概念。rabbitmq
2.发布订阅模式
发布订阅模式使得发送者和接收者之间的耦合关系变得更为松散,发送者不必关心接收者的目的地址,而接收者也不必关心消息的发送地址,而只是根据消息的主题进行消息的收发。
3.群集模式(cluster)
群集类似于一个域(Domain),群集内部的队列管理器之间通讯时,不需要两两之间建立消息通道,而是采用群集(Cluster)通道与其它成员通讯,从而大大简化了系统配置。此外,群集中的队列管理器之间能够自动进行负载均衡,当某一队列管理器出现故障时,其它队列管理器可以接管它的工作,从而大大提高系统的高可靠性。rocketmq kafka
有消费者组的概念。消费者可以组成消费者集群,可以有多个消费者集群。没有消费者集群有多个消费者,没有消息可以被多个消费者集群消费,但是每个消费者集群中的消费者只能消费一次,如果消费者集群中有消费者宕机其他消费者也可以消费可用性更好。或者不同的消费者集群做不同的业务。安全性可用性都更好。
4.为什么使用消费队列
核心就是异步、削峰、解耦
1.应用解耦
原业务场景:
快递投柜 – 扣减系统费 – 短信通知用户 – 通知快递公司
mq改造过后的业务场景
快递投柜 – MQ
MQ – 扣减系统费
MQ – 短信通知用户
MQ – 通知快递公司
子系统故障不会影响上游系统
不过这样的业务场景也并非MQ不可,单纯的应用解耦完全可以用设计模式例如观察者模式、装饰者模式+工厂模式等等。
2.异步
原业务场景:
快递投柜 – 扣减系统费 (5s)-- 短信通知用户(5s) – 通知快递公司 (5s)
共15s
mq改造过后的业务场景
快递投柜 – MQ (1s内直接返回)
其他场景异步处理:
MQ – 扣减系统费 (5s)
MQ – 短信通知用户(5s)
MQ – 通知快递公司(5s)
不过这样的业务场景也并非MQ不可,单纯需要异步的业务场景可以用异步线程(CompleteFuture)等方式。
3.流量削峰
业务场景:
高峰到40W每秒,但是我们后续处理业务只能20W每秒,剩下20W在MQ进行堆积,这就是MQ很重要的削峰能力,将用户的洪峰流量让后台来慢慢处理MQ承担一个缓冲的作用。时间换空间的思想。
流量太大了系统扛不住了,这样的业务场景MQ是比较好的解决方案削峰填谷。这样的场景限流、加服务器等是不可取的只能用MQ来处理,不能将用户拒之门外。
5.消息队列的缺点:
1.系统的可用性降低
MQ出现问题后整个系统链路都会断开 前后端无法通讯。
2.系统复杂性提高
在使用消息队列的过程中难免出现生产者、mq、消费者宕机不可用的情况,那么随之带来的问题就是消息重复,消息乱序,消息堆积等等问题都需要我们来控制。
3.一致性问题
比如上面的场景:
MQ – 扣减系统费 (5s)
MQ – 短信通知用户(5s)
MQ – 通知快递公司(5s)
扣减系统费失败了 其他两个成功了 这样就出现了一致性问题。通知用户也通知快递公司了不扣费怎么行呢?
出现了这样的问题需要应对方案,比如重试等等。
所以mq提升了系统的复杂度,能不用最好就不用,当然了必要的场景肯定还是要用。
2.消息队列的选型
推荐使用社区活跃经过大规模吞吐量场景验证的mq。例如最早的activemq就别用了。
1.RabbitMQ
用erlang语言开发,使用的是AMQP协议(高级消息队列协议)。支持多种客户端,除了看不懂源码 易用性 拓展性 可用性等方面还是不错的。
1.特性:
1.性能很好,延时比较低(指的是从队列到消费者的时间 rabbitmq用的是推模型 mq的broker主动推送消息到消费者延迟是微秒级的 通常用的rocketmq、kafka是拉模型消费者不断的轮询向mq的broker拉取消息这个延迟是毫秒级的,不过拉模式是消费者消费完了再去拉,推模型会一直推不会考虑消费者能不能消费都会一直推)。
2.吞吐量万级,MQ功能比较完备
3.开源提供的管理界面非常棒,用起来很好用。这个是最大的优点。
4.社区比较活跃
2.使用建议
大家开始用 RabbitMQ,但是确实 erlang 语言阻止了大量的 Java 工程师去深入研究和掌控它,对公司而言,几乎处于不可控的状态,但是确实人家是开源的,比较稳定的支持,活跃度也高,所以技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择,没有过高自信的话,可以使用RabbitMQ有活跃的开源社区
2.kafka
Kafka主打的是性能,是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。不过它的mq性能不是很完善不太适合业务开发,性能特别高,主要是大数据领域。
1.特性
1.具有可回溯性。通过其磁盘数据结构提供消息的持久化,文件追加的方式写入数据,过期的数据定期删除。
2.高吞吐量:每秒数百万的消息
3.支持通过kafka的服务器和消费集群来分区消息
4.执行hadoop并行数据加载。
2.使用建议
如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况kafka几乎是全世界这个领域的标杆。
3.应用场景
1.日志收集
2.消息系统
3.用户活动跟踪
4.运营指标
5.流式处理
3.RocketMQ
rocketmq主打的是业务处理安全稳得消息不丢失,可以严格有序,是阿里开源的消息中间件纯java语言开发,具有高吞吐量高可用性适合大规模分布式系统应用的特点。rocketmq思路源于kafka具有后发的优势,对消息的可靠性传输以及事务性做了优化,有双11的验证。
1.特性:
1.接口简单易用,可自定义MQ
2.topic可以达到几百,几千个的级别,吞吐量会有较小幅度的下降
3.消息可用性极高,经过参数优化配置,可以做到0丢失
4.MQ功能较为完善,还是分布式的,扩展性好
2.使用建议
纯java写的,社区可能有突然黄掉的风险(目前 RocketMQ 已捐给Apache,但 GitHub 上的活跃度其实不算高)对自己公司技术实力有绝对自信的,推荐用 RocketMQ,否则回去老老实实用 RabbitMQ 吧,大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。
4.怎么选型MQ
考虑公司产品几年内的发展,吞吐量预测,可用性要求,易用性要求等等。
RabbitMQ :erlang开发,对消息堆积的支持并不好,当大量消息积压的时候,会导致RabbitMQ 的性能急剧下降,每秒钟可以处理几万到十几万条消息。
RocketMQ :java开发,面向互联网集群化功能丰富,对在线业务的响应时延做了很多的优化,大多数情况下可以做到毫秒级的响应,每秒钟大概能处理几十万条消息。
Kafka:Scala开发,面向日志功能丰富,性能最高,当你的业务场景中,每秒钟消息数量没有那么多的时候,Kafka 的时延反而会比较高,所以,Kafka 不太适合在线业务场景。
ActiveMQ:java开发,简单,稳定,性能不如前面三个,小型系统用也ok,但是不推荐,推荐用互联网主流的。
特性 | ActiveMQ | RabbitMQ | Kafka | RocketMQ |
---|---|---|---|---|
PRODUCER0-COMSUMER | 支持 | 支持 | 支持 | 支持 |
PUBLISH-SUBSCRIBE | 支持 | 支持 | 支持 | 支持 |
REQUEST-REPLY | 支持 | 支持 | - | 支持 |
API完备性 | 高 | 高 | 高 | 低(静态配置) |
单机呑吐量 | 万级 | 万级 | 十万级 | 单机万级 |
消息延迟 | 毫秒级 | 微秒级 | 毫秒级 | 毫秒级 |
可用性 | 高(主从) | 高(主从) | 很高(分布式) | 非常高(分布式) |
消息丢失 | - | 低 | 理论上不会丢失 | 理论上不会丢失 |
消息重复 | - | 可控制 | 理论上会有重复 | 允许重复 |
文档的完备性 | 高 | 高 | 高 | 中 |
提供快速入门 | 有 | 有 | 有 | 无 |
首次部署难度 | - | 低 | 中 | 高 |
个人建议:
中小型公司技术整体能力一般可以考虑用 RabbitMQ有活跃的社区;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择;实时计算、日志采集:使用 kafka;