一、为什么使用消息队列(MQ)

核心:解耦、异步、削峰。

(1)、异步

kafka redis 消息队列 kafka消息队列的缺点_面试

 (2)、解耦

kafka redis 消息队列 kafka消息队列的缺点_面试_02

  (2)、削峰

kafka redis 消息队列 kafka消息队列的缺点_kafka_03

 二、如何选择合适的消息队列

2.1 rabbitmq

kafka redis 消息队列 kafka消息队列的缺点_消息队列_04

特点:轻量级、迅捷,开箱即用的消息队列。

缺点:(1)、对消息的堆积的支持并不友好,当大量消息积压的时候,会导致rabbitmq的性能急剧下降。

   (2)、性能是目前常用消息队列中最差的,大概美标中可以处理几万到十几万条消息。如果应用对消息队列的性能要求非常高,那么不要选择。     

           (3)、使用的编程语言是Erlang,扩展和二次开发成本高。

2.2 kafka

kafka redis 消息队列 kafka消息队列的缺点_kafka_05

依赖于zookeeper(服务的注册与发现)。kafka是一个分布式消息发布订阅系统,在消息的可靠性、稳定性和功能特性等方面都可以满足绝大多数

场景的需求。kafka与周边生态系统的兼容性是最好的没有之一,尤其在大数据和流计算领域,几乎所有的相关开源软件系统都会优先支持kafka。

kafka性能高效、可扩展性良好并且可持久化。他的分区特性,可复制和可容错都是不错的特性。在设计上大量使用了批量和异步的思想,使得kafka

能做到超高的性能。kafka的性能,尤其是异步收发的性能,是三者中最好的,大约每秒可以处理几十万条消息。

缺点:异步批量设计带来的问题是,他的同步收发消息的响应延时比较高,应为当客户端发送一条消息的时候,kafka不会立即发送出去,而是要等一会儿

攒一批再发送。所以,kafka不太适合在线业务场景。topic达到上百个时,吞吐量会大幅下降。

2.3 RocketMq

 

kafka redis 消息队列 kafka消息队列的缺点_消息队列_06

 阿里使用Java语言开发,在设计上参考了kafka,并做了自己的一些改进。有着不错的稳定性和可靠性。阿里内部被广泛应用在订单、交易、充值、流计算、消息推送,日志流式处理,binglog分发等场景。有非常活跃的中文社区,大多数问题都可以找到中文的答案。易扩展或二次开发。对在线业务的响应时延做了很多优化,如果很在意响应时延,可以选择它。而且他的性能比rabbitmq要高一个数量级。

缺点:与周边生态系统的集成和兼容程度不够。

2.4 kafka、activemq、rabbitmq、rocketmq对比

(1)、activemq:jms规范,支持事务、支持XA协议,没有生产大规模支撑场景、官方维护越来越少,吞吐量单机在万级。

(2)、rabbitmq:【优点】erlang语言开发、性能好、高并发、高可靠,吞吐量单机在万级。支持多种语言,社区、文档方面有优势。【缺点】erlang语言不利于Java程序员的二次开发每一栏开源社区的维护和升级,需要学习AMQP协议,学习成本相对较高,吞吐量比较低,消息积累会严重影响性能。【使用场景】小规模场景

(3)、kafka:【优点】高性能,高可用,生产环境有大规模使用场景,吞吐量单机百万。 【缺点】会丢失数据,功能比较单一单机容量有限(唱过64个分区相应时间明显变长),社区更新慢。【使用场景】日志分析,大数据采集。

(4)、rocketmq:【优点】Java实现,方便二次开发,设计参考了kafka,高可用、高可靠,吞吐量单机十万,高吞吐,功能全面。【缺点】社区活跃度一般,支持语言较少,开源版功能不如商业版本。官方文档和周边生态不够成熟。客户端只支持java。【使用场景】几乎全场景。

 三 MQ如何保证消费幂等性

所有MQ产品并没有提供主动解决幂等性的机制,需要消费者自行控制。

RocketMQ:给每个消息分配了MessageID。这个MessageID既可以作为消费者判断幂等性的依据。【这种方式不太建议,最好的方式就是自己带一个具有业务标识的ID,来进行幂等性判断。】

 四 如何保证消息的顺序

全局有序和局部有序:MQ只需要保证局部有序,不需要保证全局有序。

生产者把一组有序的消息放到同一个队列当中,而消费者一次消费整个队列当中的消息。

RocketMQ中有完整的设计,但是rabbitmq和kafka当中,需要自己进行设计。

 rabbitmq要保证目标exchange只对应一个队列。

 kafka:生产者通过定制partition分配规则,将消息分配到同一个partition中。topic下只对应一个消费者。