关注设计思想、实现原理和实践方法论
消息队列的作用
1.异步处理
非必要的业务逻辑以异步方式运行,提高响应速度。多个消费者并发执行,提升系统整体性能。
2.流量控制
下游来不及处理的流量堆积在消息队列中,起到削峰填谷、保护下游的作用。
3.服务解藕
上游将消息写入消息队列,需要消息的系统自己从消息队列中订阅,上游不需要做任何修改
消息队列的缺点
增加消息队列这个环节后,消息队列本身的问题可能系统整体的可用性降低。同时,消息队列带来的消息丢失、重复消费、一致性等问题导致系统复杂度变高
消息队列选型
特性 | ActiveMQ | RabbitMQ | RocketMQ | kafka |
---|---|---|---|---|
开发语言 | java | erlang | java | scala |
单机吞吐量 | 万级 | 万级 | 10万级 | 10万级 |
时效性 | ms级 | us级 | ms级 | ms级以内 |
可用性 | 高(主从架构) | 高(主从架构) | 非常高(分布式架构) | 非常高(分布式架构) |
功能特性 | 成熟的产品,在很多公司得到应用;有较多的文档;各种协议支持较好 | 基于erlang开发,所以并发能力很强,性能极其好,延时很低; 管理界面较丰富;对消息积压支持不够好 | MQ功能比较完备,扩展性佳 | 只支持主要的MQ功能,像一些消息查询,消息回溯等功能没有提供,毕竟是为大数据准备的,在大数据领域应用广。 |
RocketMQ对在线业务的响应时延做了很多优化,大多数情况下可以做到毫秒级响应,适用于处理在线业务,如交易系统中用消息队列传递订单。Kafka设计上大量使用了批量和异步的思想,具有很高的吞吐量和异步收发性能,但同步收发消息的性能稍低,因为客户端发送一条消息时,Kafka并不会立即发送出去,而是等一会儿攒一波再发送。适用于处理海量消息,如收集日志、埋点、监控或大数据、流计算等场景。
消息积压处理
消息队列本身一般不会出现积压,一般每个消息队列节点每秒可以处理几万到十几万消息,并且能够通过水平扩展成本提升处理能力。所以出现积压,一般有两种情况:生产端变快了,消费端变慢了。
如果消费速度一直比生产速度慢,时间一长,整个系统就会出现问题。要么消息队列的存储被填满无法提供服务,要么消息丢失,都是不可接受的。所以在设计系统时一定要保证消费端的消费性能高于生产端的发送性能,这样系统才能健康地持续运行。
生产者积压
对于离线场景,可以通过批量发送的方式,提高生产能力;对于在线实时行要求高的场景,通过增加并发度来提高生产消息的能力。
消费端积压
消费端性能优化可以优化消费业务逻辑性能,也可以水平扩容,增加消费端的并发数来提升整体的消费性能。
在扩容Consumer的实例数量时,必须同步扩容主题中的分区(也叫队列)数量,确保Consumer的实例数和分区数量是相等的。如果Consumer的实例数量超过分区数量,扩容实际上没有效果,因为每个分区只能支持单线程消费。