消息队列的优缺点
优点主要三条:
- 解耦:将某一个系统隔离开,不需要考虑将自己的消息发送给谁了,只需要提交给MQ,其他的子系统直接从MQ里面取数据消费就可以了。
- 异步:就是从原来的同步调用改为异步调用,允许生产者发送消息后执行其他操作,不必等待消费者的响应。提高了系统的吞吐量和响应速度。
- 削峰:消息队列可以用来平滑的处理流量峰值,避免系统因为瞬时流量压力而崩溃,消息可以被缓存和逐渐处理。
缺点主要三点:
- 降低了系统的可用性:如果消息队列宕机了,下游的子系统就无法调用生产者产生的消息。
- 提高了系统的复杂度:例如重复消费问题,由于消息队列宕机出现的数据丢失问题,还有顺序消费问题。
- 一致性问题:例如消费者出现了问题,而生产者以及返回结果了
几种消息队列的对比
- ActiveMQ:遵循JMS(java的一种)规范,支持事务,支持XA协议,没有生产大规模支撑场景,官方维护比较少。
- RabbitMQ:erlang语言开发、性能好、高并发、支持多种语言,社区比较活跃,文档方面有优势,erlang语言不利于我们(java)二次开发,依赖开源社区维护和升级,需要学习AMQP协议,学习成本相对较高。吞吐量在万级别。
- kafka:高性能,高可用,生产环境有大规模使用场景,单机容量有限(超过64个分区响应时间明显边长),社区更新比较慢。吞吐量单机百万。
- RocketMQ:Java开发(阿里开源),方便我们二次开发,设计参考了kafka,高可用,高可靠,社区活跃度一般,支持的语言比较少,吞度量单机十万。
RocketMQ更适合对数据可靠性、实时性要求较高,且需要处理大量队列的场景,如金融交易,订单处理等。其严格的消息顺序保证,和优化的实时性机制是他在这些场景中表现出色。
而kafka更适合处理海量数据流,对数据正确性要求不是特别高的场景,如日志收集,实时分析,其高吞吐量的数据写入和读取能力以及分布式的架构使得他在处理大规模流式数据的具有优势。
消息队列的发送流程:
Rocketmq和KafKa类似(实质上,最早的Rocketmq 就是KafKa 的Java版本),一条消息从生产到被消费,将会经历三个阶段:
- 生产阶段,Producer 新建消息,而后经过网络将消息投递给 MQ Broker。这个发送可能会发生丢失,比如网络延迟不可达等。
- 存储阶段,消息将会存储在 Broker 端磁盘中,Broker 根据刷盘策略持久化到硬盘中,刚收到Producer的消息在内存中了,但是如果Broker 异常宕机了,导致消息丢失。
- 消费阶段, Consumer 将会从 Broker 拉取消息。
以上任何一个阶段,都可能出现消息的丢失,以上三个阶段0丢失就可以实现消息队列0丢失。