在直播系统中选择消息队列的考量与决策
前言
面试时面试官一问到MQ你了解吗?能讲下你们项目中MQ用来干什么吗?大多数人的第一回答是:"异步消息处理,削峰填谷",今天教你们一招能瞬间让面试官打起精神的回答,下次面试时你们可以这样说:MQ就像是一个神奇的邮递员,它可以将消息快速、可靠地传递到各个系统中,它的作用就像是一个桥梁,连接了不同的系统,使得它们能够顺畅地交流和协作。 顿时格局就上来了,这时面试官的心理活动:这小子理解总结得蛮透彻的,今天我得在MQ上多盘他几下....
业务场景
MQ使用场景介绍
- 直播间内送礼、特效、公屏、弹幕等需要用到MQ异步处理
- 分布式环境下本地缓存的刷新需要用到MQ通知刷缓存
- 耗时长/并发高的业务需要用到MQ做削峰填谷
- 不同微服务中需要用到MQ做系统解耦
- 分布式微服务环境下需要广播、集群、延迟消费,有时甚至需要使用事务消费解决分布式事务问题
MQ选型要求
- 需要一个可大规模集群部署(高可用性)的MQ
- 需要一个吞吐量高、延迟低的MQ
- 需要一个支持多种消费模式的MQ
- 需要一个好落地、社区较完善、易扩展的MQ
业内常用MQ
1. ActiveMQ
特点:
- 支持多种消息传输协议:ActiveMQ 支持多种消息传输协议,如 JMS、AMQP、STOMP 等。
- 支持多种消息模型:ActiveMQ 支持多种消息模型,如点对点模型、发布订阅模型等。
- 支持多种消息类型:ActiveMQ 支持多种消息类型,如文本消息、对象消息、字节消息等。
优点:
- 支持多种消息传输协议、模型和类型,灵活性较高;
- 可以方便地与 Spring 等框架进行集成。
缺点:
- ActiveMQ 的性能相对较低,不能满足高并发、高吞吐量的消息传输需求;
- 部署和配置相对复杂,需要投入大量的时间和精力。
使用场景:
- 需要与其他JMS规范的系统集成;
- 需要支持多种协议的通信;
- 对性能要求不高的中小型系统。
使用上可能存在的坑:
- JMS API 的使用问题:ActiveMQ 是基于 JMS API 的消息中间件,需要开发人员熟练掌握 JMS API 的使用方法。
- 内存泄漏问题:ActiveMQ 的性能受限于内存,如果存在内存泄漏等问题,可能会导致系统崩溃。
- 消息堆积问题:如果消费者处理消息的速度跟不上生产者的速度,可能会导致消息堆积。需要根据实际情况来调整消费者的数量和速度。
ActiveMQ适合用于分布式系统之间的消息通信、异步任务处理等应用场景。
2. RabbitMQ
特点:
- 高度可靠性:RabbitMQ 提供了多种可靠性保证机制,如消息确认机制、持久化等。
- 良好的性能:RabbitMQ 的性能优秀,能够支持高并发、高吞吐量的消息传输。
- 灵活的路由:RabbitMQ 支持灵活的路由策略,能够满足不同场景下的需求。
优点:
- 提供了多种可靠性保证机制,消息不易丢失;
- 性能优秀,支持高并发、高吞吐量的消息传输;
- 灵活的路由策略,满足不同场景下的需求。
缺点:
- 部署和配置比较复杂;
- RabbitMQ 仅支持单个节点的横向扩展,不支持集群的纵向扩展。
使用场景:
- 对性能要求较高的大规模系统;
- 需要支持多种协议的通信;
- 对消息传输的稳定性和可靠性要求较高的系统。
使用上可能存在的坑:
- 配置文件问题:在 RabbitMQ 的配置文件中,可能存在一些常见的坑点,如配置文件缺失、配置不当等。
- 内存问题:RabbitMQ 的性能受限于内存,因此需要根据实际需求来分配内存。
- 消息丢失问题:如果 RabbitMQ 节点宕机或者网络故障,可能会导致消息丢失。需要使用可靠的消息投递机制(如消息确认机制)来保证消息的可靠性。
RabbitMQ 适合用于任务分发、消息通知、日志处理、大数据处理、在线聊天等应用场景。
3. Kafka
特点:
- 支持高吞吐量的消息传输;
- 支持消息的批量处理和压缩;
- 支持分布式部署;
- 具有较好的性能和可靠性。
优点:
- 性能极佳,支持高并发和大规模的消息传输;
- 支持多种特性,如消息压缩、批量处理等;
- 具有良好的可扩展性和可靠性。
缺点:
- 功能较为简单,不支持复杂的消息处理场景;
- 社区支持相对较少。
使用场景:
- 对性能要求极高的大规模系统;
- 对消息传输的可靠性和稳定性要求较高的系统。
使用上可能存在的坑:
- 配置问题:Kafka 的配置非常灵活,但也容易出错。需要根据实际需求来配置 Kafka 的参数。
- 磁盘空间问题:Kafka 存储所有的消息数据,因此需要足够的磁盘空间来存储数据。
- 服务异常问题:Kafka 的服务可能因为各种原因异常,需要监控服务状态并及时处理。
Kafka适合用于日志处理、实时数据处理、流式处理等应用场景。
4. RocketMQ
特点:
- 支持主从架构和Broker集群;
- 支持消息的有序传输和有序消费;
- 支持高可用和消息事务等特性;
- 具有较好的性能和可靠性。
优点:
- 高可用性,支持主从架构和Broker集群;
- 对消息的有序传输和有序消费支持较好;
- 支持事务消息,保证消息传输的可靠性;
- 性能较为优秀,支持高并发和大规模的消息传输。
缺点:
- 社区相对较小,文档资料相对较少;
- 部署和配置相对较为复杂。
使用场景:
- 对可用性和消息传输的可靠性要求较高的大规模系统;
- 需要支持有序消息传输和消费的系统;
- 对消息事务有较高要求的系统;
- 需要支持大规模数据传输和高并发的系统。
使用上可能存在的坑:
- 服务端配置问题:RocketMQ 的性能受限于服务端的配置,需要根据实际需求来配置服务端参数。
- 客户端使用问题:RocketMQ 的客户端使用比较复杂,需要开发人员熟练掌握客户端的使用方法。
- 消息消费问题:RocketMQ 的消息消费可能存在重复消费、消息丢失等问题,需要使用可靠的消息消费机制来保证消息的正确性。
RocketMQ适合用于高并发、大数据量、有序消息传输、分布式事务等应用场景。
5. Redis
不要笑,真的可以用来做MQ,你要知道并不是所有的业务都需要消息高可用的,甚至有些业务允许你丢消息,所以它也是适用于某些场景的。
特点:
- 基于内存存储,读写速度快;
- 支持多种数据结构,如List、Set、Hash等;
- 支持多种消息模式,如发布/订阅、点对点等;
- 支持消息持久化。
优点:
- 高性能,读写速度快;
- 可以使用多种数据结构存储数据,比传统MQ更加灵活;
- 支持多种消息模式,可以适应不同的业务需求;
- 可以使用AOF和RDB两种方式进行数据持久化,保证消息不丢失。
缺点:
- 不支持消息的事务处理;
- 不支持消息的回溯和消费确认;
- 单机性能受限,不适用于大规模集群。
使用场景:
- 适合对性能要求较高的业务场景,如实时性要求高的在线游戏、实时消息推送等;
- 适合对数据结构存储需求较多的场景,如分布式缓存、统计数据聚合等;
- 适合对消息发布/订阅需求较多的场景,如消息通知、实时广播等;
- 适合对轻量级MQ系统的需求,如小型项目、中小企业等。
使用上可能存在的坑:
- 持久化配置问题:Redis 支持多种持久化方式,需要根据实际需求来配置持久化方式和参数。
- 内存问题:Redis 的性能受限于内存,需要根据实际需求来分配内存。
- 客户端连接问题:Redis 的客户端连接可能存在超时、重试等问题,需要使用可靠的连接机制来保证客户端的稳定性。
Redis做MQ系统,可以为一些小型或中小型的应用提供简单、高性能、灵活的消息传输服务,但是对于大规模集群或高并发的业务场景来说,显然不适用。
选型分析
RabbitMQ | 高 | 中 | 低 | 低 | 企业级应用,大规模数据处理,传输可靠性要求高的场景 | 微软、VMware、华为 |
Kafka | 高 | 高 | 低 | 中 | 流式处理,大数据量场景,高吞吐低延迟的实时消息处理 | Netflix、LinkedIn、Uber |
ActiveMQ | 中 | 中 | 中 | 低 | 适用于较小规模的应用,消息传输可靠性要求一般的场景 | Apache、Adobe、Red Hat |
RocketMQ | 高 | 高 | 低 | 中 | 高并发、高吞吐量,低延迟的互联网应用场景 | 阿里巴巴、美团、京东 |
Redis | 中 | 高 | 极低 | 中 | 缓存和计算场景,数据量较小,对延迟要求极高的实时应用 | Twitter、GitHub、滴滴 |
业务场景可行性分析
- RabbitMQ:RabbitMQ适用于传输可靠性要求较高的企业级应用,但在高并发、高吞吐量和低延迟的社交直播场景中可能存在性能瓶颈。
- Kafka:Kafka具有高吞吐量和低延迟的特点,适用于处理海量数据和实时流式处理的场景,但在社交直播场景中可能存在实时性不足的问题。
- ActiveMQ:ActiveMQ适用于传输一般性质的消息,但在高并发、高吞吐量和低延迟的社交直播场景中可能存在性能瓶颈。
- RocketMQ:RocketMQ适用于高并发、高吞吐量和低延迟的互联网应用场景,支持多语言客户端和分布式事务,具有高可用性和性能表现。在社交直播场景中,RocketMQ可以满足高并发、高吞吐量和低延迟的消息交互和推送需求。
- Redis:Redis主要用于缓存和计算场景,对延迟要求极高的实时应用,但在社交直播场景中可能存在消息不可靠、数据量过大的问题。
最终方案确认
综合考虑以上因素,我们选择RocketMQ作为社交直播应用中的消息队列。RocketMQ具有高并发、高吞吐量和低延迟的特点,可以满足实时消息交互和推送的需求。此外,RocketMQ还支持分布式事务和多语言客户端,可以保证数据传输的可靠性和灵活性
为什么是RocketMQ而不是Kafka?
再次回答一下来自标题的灵魂发问,我知道其实很多大厂都在用着Kafka,它在高吞吐量、低延迟、可扩展性、活跃的开源社区等方面表现出色,这些因素都是其受大厂欢迎的主要原因之一,也是很多大型企业选择使用Kafka的原因。
为什么选择RocketMQ,不是因为它比Kafka多优秀,主要有以下几个原因:
- 实时性要求更高:社交直播应用需要实时的消息交互和推送,因此消息队列需要具备低延迟的特点。虽然Kafka也具有低延迟的特点,但是相较于RocketMQ,其设计和实现更偏向于数据流处理,而不是面向实时消息的传输,可能不太适合社交直播场景的实时性要求。
- 开发效率更高:RocketMQ具有简单易用的API和广泛的客户端支持,可以在社交直播场景中提高开发效率。而Kafka的客户端相对较少,需要使用者自行编写定制化代码,这可能会增加开发难度和复杂度。
- 更好的容错性和可靠性:在社交直播场景中,消息丢失或传输失败可能会对用户体验产生负面影响。RocketMQ在容错性和可靠性方面设计得更为严格和稳定,具有更好的消息可靠性和数据一致性。Kafka在这方面的表现也非常优秀,但相比之下,RocketMQ在此方面的表现可能更为稳定。
所以总之一句话就是,RocketMQ会被我们优先选择,而Kafka可能不太适合在社交直播场景中使用。
RocketMQ在云原生上的表现
- 容器化支持:RocketMQ已经容器化,可以方便地在云原生环境中部署和管理,如Kubernetes。
- 弹性伸缩:RocketMQ支持按需伸缩,可以根据业务负载自动伸缩,提高了消息系统的可用性和可扩展性。
- 高可用性:RocketMQ提供了主从复制和多活部署等机制,能够保证消息系统的高可用性,避免了单点故障。
- 可观测性:RocketMQ提供了完善的监控和告警系统,可以方便地观测消息系统的运行状态,及时发现并解决问题。
- 开放性:RocketMQ是一款开源的消息中间件,支持多种编程语言和平台,可以方便地集成到各种分布式系统中。
RocketMQ在云原生时代的支持与优势非常明显,可以帮助用户更好地构建可靠、高效、高可用的分布式消息系统。
#从0到1千万级直播项目#文章内容源自本人所在互联网社交企业实战项目,分享、记录从0-1做一个千万级直播项目,内容包括高并发场景下技术选型、架构设计、业务解决方案等。