为何使用消息中间件:1:复杂系统的解耦 2:复杂链路的异步调用 3:瞬时高峰的削峰处理
使用消息中间件带来的缺点:1:系统可用性降低(万一MQ突然挂掉) 2:系统稳定性降低(消息丢失,消息重复,系统宕机导致的消息积压)3:分布式一致性问题 生产者发送成功 消费者消费失败
优点 | 缺点 | |
ActiveMQ | 老牌消息中间件 | 没法确认ActiveMQ可以支撑互联网的高并发, 高负载以及高吞吐的复杂场景,国内互联网公司落地较少;使用较多的是一些传统企业, 用ActiveMQ做异步调用和系统解耦 |
RabbitMQ | 支撑高并发、高吞吐、性能很高, 同时有非常完善便捷的后台管理界面,支持集群化、高可用部署架构、消息高可靠支持,功能较为完善;进过调研,国内各大互联网公司落地大规模RabbitMQ集群支撑自身业务的case较多,国内各种中小型互联网公司使用RabbitMQ的实践也比较多 | 基于erlang语言开发,难以分析源码,比较难进行深层次的源码定制和改造 |
RocketMQ | 阿里开源,经过阿里的生产环境的超高并发、高吞吐的考验,性能卓越,同时支持分布式事务等特殊场景,基于java语言开发适合深入阅读源码 | |
Kafka | 专为超高吞吐量的实时日志采集、实时数据同步、实时数据计算等场景, 因此Kafka在大数据领域中配合实时计算计算(比如Spark Streaming、Storm、Flink) 使用比较多。 | 在传统的MQ中间件使用场景中较少采用 |
线上服务宕机时,如何保证数据100%不丢失:
发送方 ConfirmCallback 设为 true 开启发送确认 ;
ReturnCallback 设为 true 开启发送失败退回
如果消息没有到exchange,则confirm回调,ack=false
如果消息到达exchange,则confirm回调,ack=true
exchange到queue成功,则不回调return
exchange到queue失败,则回调return(需设置mandatory=true,否则不回回调,消息就丢了)
消费方设置手动 ack
消费成功 :channel.basicAck() 告知服务器,消息消费成功,队列可以删除这条消息了
消费失败: channel.basicNack()丢弃这条消息 ack返回false,并重新回到队列