消息队列简介
消息队列简介
为什么使用消息队列
消息队列的常用场景有很多,比较核心的有 3 个:异步、解耦、削峰
异步
用户下一个订单会涉及到的业务线:【扣库存】->【生成订单】->【短信服务】->【积分服务】。如果是同步操作的话,业务处理线会比较长,耗时相当于要 15ms
如果加入了消息队列,这个时候的情况就发生改变了,用户下一个订单会涉及到的业务线只有【扣库存】->【生成订单】,接着只要把消息写入到消息队列后业务就结束了,对于用户来说感知到耗时 6ms 就下单成功了。消息将通过异步的方式发送给【短信服务】和【积分服务】
此外异步还有第二个好处:在进行短信发送的时候,假设短信的上游厂商出现了程序问题,当短信服务商的系统恢复后依然可以通过异步的方式发送短信给用户。如果采用同步的方式就会影响到用户的下单
解耦
在上述的业务场景中,后续是有【短信服务】和【积分服务】,但如果产品经理提出了需要增加【营销服务】和对生成的订单做一个【数据分析】。如果没有消息队列,你会发现我们需要去改动【生成订单】后的业务逻辑代码
当加入了消息队列后,这个时候是解耦的,后续新增的业务对前面的【扣库存】以及【生成订单】是没有影响的。只需新增【营销服务】【数据分析】这两个消费者去订阅对应的主题即可
削峰
假设在每天的 0 点到 16 点,A 系统风平浪静,每秒并发请求数量只有 100 个。结果一到 16 点~ 23 点期间,每秒并发请求数量会暴增到 1 万 条。但是系统最大的处理能力就只能是每秒钟处理 1000 个请求。这时我们需要对流量进行削峰,让系统可以平缓地处理突增的请求
消息队列还有一个很重要的功能:可以暂存请求,每秒钟多余的未处理的 9000 条业务可以存到消息队列中,让系统平缓地处理,相当于用时间来换取空间,这称之为削峰
如何选择合适的消息队列
RabbitMQ
RabbitMQ 于 2007 年发布,是使用 Erlang 编程语言编写的,最早是为电信行业系统之间的可靠通信设计的,也是少数几个支持 AMQP 协议的消息队列之一
RabbitMQ:轻量级、迅捷、它的宣传口号也是很明确的表明了 RabbitMQ 的特点:Messaging that just works,开箱即用的消息队列。也就是说它是一个相当轻量级的消息队列,非常容易部署和使用
RabbitMQ 的客户端支持的编程语言大概是所有消息队列中最多的
RabbitMQ 存在的问题:
RabbitMQ 对消息堆积的支持并不好,当有大量消息积压的时候会导致性能的急剧下降
RabbitMQ 的性能是几个消息队列中最差的,大概每秒可以处理几万到几十万条消息。如果应用对消息队列的性能要求非常高,不建议使用
RabbitMQ 使用的编程语言 Erlang,扩展和二次开发的成本比较高
Kafka
Kafka 是依赖于 Zookeeper 的。如果你安装 Kafka ,得先安装一个 Zookeeper 去做一个服务的注册与发现
Apache Kafka 是一个分布式消息发布订阅系统。它最初由 Linkedln 公司基于独特的设计实现为一个分布式的日志提交系统,之后成为 Apache 项目的一部分
Kafka 与周边生态系统的兼容性是最好的没有之一,尤其在大数据和流计算领域,几乎所有的相关开源软件系统都会优先支持 Kafka
Kafka 性能高效,可扩展性良好并且可持久化。它的分区特性,可复制和可容错都是不错的特性
Kafka 使用 Scala 和 Java 语言开发,设计上大量使用了批量和异步的思想,使得 Kafka 能做到超高的性能
如果有足够的客户端并发进行异步批量发送切开启压缩的情况下,Kafka 的极限处理能力可以超过每秒 2000 万条消息
Kafka 存在的问题:
Kafka 异步批量处理的设计带来的问题是,它的同步收发消息的响应时延比较高,因为当客户端发送一条消息时,Kafka 并不会立即发送出去,而是要等一会攒一批再发送,在它的 Broker 中,很多地方都会使用这种先攒一批再一起处理的设计。因此当您的业务场景中,每秒钟消息数量没有那么多的时候,Kafka 的时延反而会比较高
topic 达到上百个的时候,吞吐量会大幅下降。所以像电商场景中有几百个主题的,就不太适用 Kafka。反而适合使用在日志场景中,因为日志场景里的主题相对比较少
RockerMQ
RocketMQ 是由阿里捐赠给 Apache 的一款低延迟、高并发、高可用、高可靠的分布式消息中间件。经历了淘宝双十一的洗礼。RocketMQ 既可为分布式应用系统提供异步解耦和削峰填谷的能力,同时也具备互联网应用所需的海量消息堆积、高吞吐、可靠重试等特性
RocketMQ 的性能比 RabbitMQ 要高一个数量级,每秒钟大概能处理几十万条消息
RocketMQ 对在线业务的响应时延做了很多的优化,大多数情况下可以做到毫秒级的响应,如果你的应用场景很在意响应时延,可以选择使用 RocketMQ
RockerMQ 存在的问题:
- 与周边生态系统的集成和兼容程度不够