一、为什么使用消息队列(MQ)
核心:解耦、异步、削峰。
(1)、异步
(2)、解耦
(2)、削峰
二、如何选择合适的消息队列
2.1 rabbitmq
特点:轻量级、迅捷,开箱即用的消息队列。
缺点:(1)、对消息的堆积的支持并不友好,当大量消息积压的时候,会导致rabbitmq的性能急剧下降。
(2)、性能是目前常用消息队列中最差的,大概美标中可以处理几万到十几万条消息。如果应用对消息队列的性能要求非常高,那么不要选择。
(3)、使用的编程语言是Erlang,扩展和二次开发成本高。
2.2 kafka
依赖于zookeeper(服务的注册与发现)。kafka是一个分布式消息发布订阅系统,在消息的可靠性、稳定性和功能特性等方面都可以满足绝大多数
场景的需求。kafka与周边生态系统的兼容性是最好的没有之一,尤其在大数据和流计算领域,几乎所有的相关开源软件系统都会优先支持kafka。
kafka性能高效、可扩展性良好并且可持久化。他的分区特性,可复制和可容错都是不错的特性。在设计上大量使用了批量和异步的思想,使得kafka
能做到超高的性能。kafka的性能,尤其是异步收发的性能,是三者中最好的,大约每秒可以处理几十万条消息。
缺点:异步批量设计带来的问题是,他的同步收发消息的响应延时比较高,应为当客户端发送一条消息的时候,kafka不会立即发送出去,而是要等一会儿
攒一批再发送。所以,kafka不太适合在线业务场景。topic达到上百个时,吞吐量会大幅下降。
2.3 RocketMq
阿里使用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下只对应一个消费者。