什么是MQ? MQ怎么选择?(详细解释)

什么是MQ?

 MQ(message queue),从字面意思上看,本质是个队列,FIFO先入先出,是一种通信方式,允许分布式系统中的不同组件通过消息传递进行通信。消息队列系统提供了一个缓冲区,通过该缓冲区可以存储和传递消息,确保消息在组件之间的可靠传递和处理。在互联网架构中,MQ是一种非常常见的上下游“逻辑解耦+物理解耦”的消息通信服务。使用了MQ之后,消息发送上游只需要依赖MQ,不用依赖其他服务。

MQ有什么好处?

   异步通信

    • 消息发送者和接收者不需要同时处于活跃状态。发送者可以将消息放入队列中,而接收者可以在方便的时候读取和处理消息。

        有些服务间调用并不需要知道服务调用结果,是异步的,例如A执行完需要调用B,让B进行状态修改,B需要花费很长时间执行,但是A不需要知道B什么时候可以执行完也不需要B的执行结果,分布式系统中经常会使用A在执行完之后调用B的API方法,这种方式会阻塞A的执行,不是很优雅,A会等待B的调用结果,使用消息队列,可以很方便解决这个问题,A执行完业务之后,将消息发送到消息队列,B只需要拉取消息完成业务即可,并不会阻塞A的执行。这样A服务既不用循环调用B的查询api,也不用提供callback api。同样B服务也不用做这些操作。A服务还能及时的得到异步处理成功的消息。

同步调用优势:时效性强,等待到结果后才返回

同步调用问题:拓展性差,性能下降

异步调用优势:耦合度低,拓展性强;异步调用,无需等待,性能好;故障隔离,下游服务故障不影响上游业务;缓存消息,流量削峰填谷。

异步调用问题:不能立即得到调用结果,时效性差;不确定下游业务执行是否成功;业务安全依赖于broker 的可靠性。

  解耦

    • 生产者和消费者之间解耦,生产者只需知道消息队列的地址,而不需要知道消费者的具体信息。这使得系统的各个组件可以独立地演化和扩展。

以电商应用为例,应用中有订单系统、库存系统、支付系统。用户创建订单后,如果耦合调用库存系统、物流系统、支付系统,任何一个子系统出了故障,都会造成下单操作异常。当转变成基于消息队列的方式后,系统间调用的问题会减少很多,比如物流系统因为发生故障,需要几分钟来修复。在这几分钟的时间里,物流系统要处理的内存被缓存在消息队列中,用户的下单操作可以正常完成。当物流系统恢复后,继续处理订单信息即可 ,下单用户感受不到物流系统的故障,提升系统的可用性。

  负载均衡

    • 多个消费者可以从同一个队列中消费消息,实现负载均衡。消息队列系统会自动将消息分配给多个消费者,从而提高系统的处理能力。
  1. 持久化

    • 消息可以持久化存储在磁盘中,确保在系统崩溃或网络故障时消息不会丢失。
  1. 顺序保证

    • 可以保证消息在某些场景下按顺序处理,确保系统处理流程的正确性。

MQ分类

rabbit MQ:

优点:

  1. 支持多种消息传递模式
    • RabbitMQ 支持点对点(queue-based)、发布/订阅(pub/sub)、工作队列(work queues)、路由(routing)和主题(topic)等多种消息传递模式,适用于不同的应用场景。
  1. 可靠性
    • RabbitMQ 提供消息确认机制,确保消息在消费者成功处理后才从队列中删除。它还支持持久化消息和队列,保证在服务器重启后消息不会丢失。
  1. 灵活的路由功能
    • RabbitMQ 使用交换机(exchange)和绑定(binding)机制,提供灵活的消息路由功能。通过不同类型的交换机(如 direct、topic、fanout 和 headers),可以实现复杂的路由逻辑。
  1. 可扩展性
    • RabbitMQ 支持集群配置,通过将多个 RabbitMQ 节点组成集群,可以实现负载均衡和高可用性。同时,它还支持联邦模式(federation)和分布式交换(shovel)功能,跨数据中心同步消息。
  1. 多语言客户端支持
    • RabbitMQ 提供了丰富的客户端库,支持多种编程语言(如 Java、Python、Ruby、.NET、PHP、Go 等),方便开发者集成到不同的应用中。
  1. 管理工具
    • RabbitMQ 提供了强大的管理插件(RabbitMQ Management Plugin),通过 Web 界面可以方便地监控和管理 RabbitMQ 实例、队列、交换机和连接等信息。
  1. 插件系统
    • RabbitMQ 拥有灵活的插件系统,支持自定义扩展。开发者可以根据需求编写和安装插件,增加 RabbitMQ 的功能。

缺点:

  1. 性能瓶颈
    • 虽然 RabbitMQ 在处理大量小消息时表现良好,但在高吞吐量场景下(如处理每秒数百万条消息),性能可能会受到限制。Kafka 在这种高吞吐量场景下通常表现更好。
  1. 复杂性
    • RabbitMQ 的配置和管理相对复杂,特别是在需要实现高可用性和分布式部署时。需要具备一定的专业知识来进行正确配置和优化。
  1. 内存消耗
    • RabbitMQ 依赖内存来存储消息队列中的消息。如果消息积压严重,可能会导致内存消耗过高,从而影响系统性能。
  1. 延迟
    • 在某些高性能和低延迟要求的场景下,RabbitMQ 的消息传递延迟可能无法满足需求。特别是在需要严格顺序保证的情况下,延迟可能会增加。
  1. 集群管理
    • RabbitMQ 集群的管理和维护相对复杂,尤其是在集群节点数较多时。需要仔细规划和配置集群,以避免数据不一致和性能问题。

active MQ:

优点:

  1. 多协议支持
    • ActiveMQ 支持多种消息协议,包括 AMQP、STOMP、MQTT、OpenWire 等,使其能够与多种不同的系统和客户端集成。
  1. 持久化和可靠性
    • ActiveMQ 支持消息持久化,确保消息在服务器重启或崩溃后不会丢失。它还提供了多种可靠性保障机制,如消息确认、事务支持等。
  1. 灵活的消息模型
    • 支持多种消息传递模型,包括点对点(Queue)、发布/订阅(Topic)、请求/响应等,满足不同应用场景的需求。
  1. 高可用性
    • ActiveMQ 支持多种集群模式,包括主-备模式(Master-Slave)和共享存储模式,提供高可用性和故障转移能力。
  1. 易于管理和监控
    • 提供了 JMX 支持和 Web 控制台,方便管理员监控和管理消息代理的运行状态、队列和主题的情况、连接信息等。
  1. 丰富的客户端支持
    • ActiveMQ 提供了丰富的客户端库,支持多种编程语言和平台,如 Java、.NET、C++、Python 等,方便开发者集成。
  1. 成熟和稳定
    • 作为一个老牌的消息队列系统,ActiveMQ 已经经过多年的发展和优化,社区活跃,文档齐全,可靠性和稳定性较高。

缺点:

  1. 性能
    • ActiveMQ 在处理高吞吐量场景时可能表现不如一些新兴的消息队列系统,如 Kafka。在处理大规模消息传递时,性能可能成为瓶颈。
  1. 集群配置复杂
    • 虽然 ActiveMQ 支持多种高可用性和集群模式,但其配置和管理相对复杂,需要一定的专业知识和经验来正确设置和维护。
  1. 内存消耗
    • ActiveMQ 依赖内存来存储消息,在消息积压严重时,可能会导致内存消耗过高,从而影响系统性能。
  1. 顺序保证
    • 在分布式环境中,保证消息的严格顺序处理可能比较困难,需要额外的配置和处理。
  1. 延迟
    • ActiveMQ 在某些场景下的消息传递延迟可能较高,特别是在需要低延迟和高并发的场景中,可能无法完全满足需求。

rocketMQ:

优点:

  1. 高吞吐量和低延迟
    • RocketMQ 经过优化,具有高吞吐量和低延迟的特点,能够在大规模分布式系统中高效处理消息。
  1. 水平扩展
    • RocketMQ 支持水平扩展,可以通过增加更多的 Broker 节点来提升系统的处理能力,适应业务增长。
  1. 丰富的消息传递模型
    • 支持点对点(Queue)和发布/订阅(Topic)模型,以及顺序消息、延迟消息、事务消息等多种消息传递方式,满足不同场景的需求。
  1. 高可用性
    • RocketMQ 支持主从架构,通过主从复制实现高可用性。主节点故障时,从节点可以迅速接管,保证系统的连续性。
  1. 强一致性保证
    • RocketMQ 提供了强一致性的消息投递,确保消息不会丢失或重复处理,适用于金融级别的可靠性要求。
  1. 灵活的消息路由
    • 支持灵活的消息路由机制,可以通过 Tag 和 Key 实现精确的消息过滤和路由。
  1. 监控和管理
    • 提供了丰富的监控和管理工具,可以通过控制台方便地查看消息堆积、消费延迟等指标,便于运维人员进行系统监控和故障排查。
  1. 事务消息
    • 支持事务消息,能够保证在分布式事务场景下消息的一致性,适用于金融、支付等对事务一致性要求较高的业务场景。

缺点:

  1. 学习曲线
    • 相对于一些老牌的消息队列系统,如 ActiveMQ 和 RabbitMQ,RocketMQ 的概念和配置可能对新手来说较为复杂,需要一定的学习和实践才能掌握。
  1. 社区和文档
    • 虽然 RocketMQ 的社区和文档在不断完善,但相对于 Kafka 等更为成熟的开源项目,仍存在一定差距,特别是在一些高级特性和优化方面的资料可能较少。
  1. 生态系统
    • 虽然 RocketMQ 提供了多语言客户端,但在一些边缘生态系统和工具的支持上,可能不如 Kafka 这样广泛应用的消息队列系统。
  1. 集群管理
    • RocketMQ 的集群管理和运维需要一定的专业知识,特别是在大规模部署和高可用配置方面,可能需要更多的经验和技巧。

Kafka:

优点:

  1. 高吞吐量
    • Kafka 设计用于高吞吐量的日志和事件数据流处理,可以每秒处理数百万条消息。它的性能得益于其顺序写入磁盘和高效的 IO 操作。
  1. 低延迟
    • Kafka 能够在毫秒级别内处理消息,从而保证了低延迟的数据传输,这对于需要实时数据处理的应用场景非常关键。
  1. 水平扩展
    • Kafka 支持通过增加更多的 Broker 节点来扩展系统的容量和处理能力。它的分区机制允许消息在多个 Broker 之间分布,实现高可用性和负载均衡。
  1. 高可靠性
    • Kafka 提供了数据复制机制,确保数据在多个 Broker 节点之间冗余存储,保证了在节点故障时数据不丢失。
  1. 消息持久化
    • Kafka 中的消息可以持久化存储在磁盘上,且持久化机制高效且可靠,支持消息的顺序读取和恢复。
  1. 灵活的消息消费模式
    • Kafka 通过消费者组实现了灵活的消息消费模式,支持点对点和发布/订阅两种模式。消费者组内的消费者可以并行处理消息,实现负载均衡。
  1. 流处理能力
    • Kafka 提供了 Kafka Streams 和 KSQL 等流处理工具,支持实时的数据流处理和复杂事件处理,满足了从消息传递到实时数据处理的需求。
  1. 强大的社区和生态系统
    • 作为一个成熟的开源项目,Kafka 拥有一个活跃的社区和丰富的生态系统,提供了丰富的文档、工具和扩展支持。

缺点:

  1. 学习曲线陡峭
    • Kafka 的概念和配置相对复杂,新手需要花费时间学习其架构、配置和最佳实践,才能充分利用 Kafka 的优势。
  1. 管理复杂
    • Kafka 的管理和运维较为复杂,尤其是在集群的部署、监控、故障排查和优化方面,需要具备一定的专业知识和经验。
  1. 消息顺序
    • Kafka 在分区级别保证消息的顺序性,但在跨分区的情况下无法保证全局顺序。如果应用需要严格的全局顺序处理,可能需要额外的设计和处理。
  1. 资源消耗
    • Kafka 对硬件资源的消耗较高,特别是对磁盘 IO 和网络带宽有较高要求。需要为 Kafka 部署提供足够的硬件资源,以保证其高性能运行。
  1. 事务支持有限
    • 虽然 Kafka 支持幂等生产者和事务性消息,但其事务支持相对有限,可能不适用于所有需要强事务性的应用场景。

场景选择:

RabbitMQ

适用场景:

  1. 企业应用集成:
    • RabbitMQ 支持 AMQP 协议,适合需要与其他系统进行标准化集成的企业应用。
  1. 复杂的路由需求:
    • RabbitMQ 提供灵活的路由功能,通过交换机和绑定可以实现复杂的消息路由逻辑。
  1. 需要可靠的消息传递:
    • RabbitMQ 支持消息确认、持久化和事务,适用于需要高可靠性的应用,如订单处理、金融交易等。
  1. 轻量级任务队列:
    • 适合用于处理轻量级的任务队列和工作队列。

为什么选择 RabbitMQ:

  • 协议支持:支持 AMQP、STOMP、MQTT 等多种协议,适用于需要标准化协议的场景。
  • 灵活性:强大的路由功能和插件系统,支持复杂的消息传递需求。
  • 易用性:丰富的客户端库和管理工具,易于集成和使用。

ActiveMQ

适用场景:

  1. 企业级消息传递:
    • ActiveMQ 支持多种协议(如 AMQP、STOMP、OpenWire 等),适合企业级应用集成和消息传递。
  1. 需要 JMS 兼容性:
    • ActiveMQ 完全兼容 Java 消息服务(JMS),适用于使用 JMS API 的 Java 企业应用。
  1. 异构系统集成:
    • 支持多种协议和客户端,适合需要集成异构系统的场景。

为什么选择 ActiveMQ:

  • 协议和标准支持:支持多种消息协议,尤其是 JMS 兼容性,使其在 Java 企业应用中广泛使用。
  • 成熟稳定:长期发展和成熟的社区支持,稳定可靠。
  • 丰富的特性:提供持久化、事务、消息优先级等高级特性。

RocketMQ

适用场景:

  1. 高吞吐量和低延迟要求:
    • RocketMQ 经过优化,适合处理高吞吐量和低延迟的消息传递,如实时数据处理、日志收集等。
  1. 分布式事务:
    • RocketMQ 支持分布式事务消息,适用于需要分布式事务保证的金融、电商等业务场景。
  1. 大数据和流处理:
    • 适合用于大数据处理和流处理场景,如实时分析、监控等。

为什么选择 RocketMQ:

  • 性能优越:高吞吐量、低延迟,适用于高性能需求的场景。
  • 事务支持:分布式事务消息支持,适用于需要强一致性保证的场景。
  • 可扩展性:支持水平扩展,能够处理大规模分布式系统的消息需求。

Kafka

适用场景:

  1. 大数据和实时数据流处理:
    • Kafka 设计用于高吞吐量和低延迟的数据流处理,适用于实时数据处理和分析场景。
  1. 日志和事件收集:
    • Kafka 广泛用于日志收集和事件流处理,如网站活动跟踪、系统日志收集等。
  1. 消息持久化和回溯:
    • Kafka 支持消息持久化和消费回溯,适用于需要持久化和历史数据处理的场景。

为什么选择 Kafka:

  • 高吞吐量和低延迟:适用于大规模数据流处理和实时分析场景。
  • 可扩展性:支持水平扩展,能够处理大规模数据流。
  • 丰富的生态系统:提供 Kafka Streams、KSQL 等流处理工具,支持复杂的数据处理需求。

总结

选择 RabbitMQ:当需要灵活的路由、高可靠性和多协议支持时,特别是在企业应用集成和轻量级任务队列场景下。

选择 ActiveMQ:当需要 JMS 兼容性、多协议支持和企业级消息传递时,特别是在异构系统集成和传统企业应用中。

选择 RocketMQ:当需要高吞吐量、低延迟和分布式事务支持时,特别是在金融、电商和实时数据处理场景中。

选择 Kafka:当需要高吞吐量、低延迟、可扩展性和持久化消息支持时,特别是在大数据、实时数据流处理和日志收集场景中。

持久化区别:

RabbitMQ

持久化机制:

  • 队列持久化:可以声明持久化队列(durable queue),确保队列在服务器重启后依然存在。
  • 消息持久化:可以将消息标记为持久化(persistent),确保消息在服务器重启后不会丢失。
  • 持久化存储:消息和队列元数据会写入磁盘,但这会增加写操作的延迟。

使用示例:

channel.queueDeclare("myQueue", true, false, false, null); // 创建持久化队列 

channel.basicPublish("", "myQueue", MessageProperties.PERSISTENT_TEXT_PLAIN, "Hello World".getBytes()); // 发送持久化消息

ActiveMQ

持久化机制:

  • 队列和主题持久化:ActiveMQ 支持持久化队列和主题,消息会存储到磁盘中。
  • KahaDB:默认的持久化存储机制,优化了磁盘 IO 操作。
  • JDBC 存储:支持将消息存储到关系数据库中。
  • 持久化策略:可以通过配置文件设置不同的持久化策略。

使用示例:

ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616"); 

Connection connection = factory.createConnection(); 
connection.start(); 
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); Destination destination = session.createQueue("myQueue"); 
MessageProducer producer = session.createProducer(destination); 

producer.setDeliveryMode(DeliveryMode.PERSISTENT); // 发送持久化消息 TextMessage 

message = session.createTextMessage("Hello World"); producer.send(message);

RocketMQ

持久化机制:

  • CommitLog:RocketMQ 使用 CommitLog 文件记录所有的消息,消息首先写入 CommitLog,然后异步刷盘到磁盘。
  • 消费队列:消费队列存储消息的逻辑偏移量,用于加快消息消费速度。
  • 消息索引:存储消息索引,以便快速检索消息。
  • 同步和异步刷盘:支持同步刷盘和异步刷盘策略,以平衡性能和数据可靠性。

使用示例:

DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName"); 
producer.setNamesrvAddr("127.0.0.1:9876"); 
producer.start(); Message msg = new Message("TopicTest", "TagA", "OrderID001", "Hello world".getBytes()); 
msg.setFlag(1); // 设置消息的 flag 位 
producer.send(msg); 
producer.shutdown();

Kafka

持久化机制:

  • 日志分段文件:Kafka 将消息写入日志分段文件(Log Segment),每个分段文件大小固定,当分段文件达到设定大小时,会创建新的分段文件。
  • 多副本机制:Kafka 支持多副本机制,每个分区的消息可以复制到多个 Broker 上,提供高可用性和容错能力。
  • 数据保留策略:可以配置消息的保留时间或保留大小,超出限制的旧消息会被删除。

使用示例:

Properties props = new Properties(); 
props.put("bootstrap.servers", "localhost:9092"); 
props.put("acks", "all"); 
props.put("retries", 0); 
props.put("batch.size", 16384); 
props.put("linger.ms", 1); 
props.put("buffer.memory", 33554432); 
props.put("key.serializer","org.apache.kafka.common.serialization.StringSerializer"); props.put("value.serializer","org.apache.kafka.common.serialization.StringSerializer"); 
Producer<String, String> producer = new KafkaProducer<>(props); 
for (int i = 0; i < 100; i++) { producer.send(new ProducerRecord<>("myTopic", Integer.toString(i), Integer.toString(i))); 
} producer.close();

总结

这四种消息队列系统都支持持久化,但其实现机制和适用场景有所不同:

RabbitMQ:适用于需要灵活路由和可靠消息传递的企业应用。

ActiveMQ:适用于需要 JMS 兼容性和多协议支持的企业级应用。

RocketMQ:适用于需要高吞吐量、低延迟和分布式事务支持的场景。

Kafka:适用于大规模数据流处理和实时分析场景,提供高吞吐量、低延迟和强持久化支持。

分布式:

RabbitMQ

分布式支持

  • 集群模式:RabbitMQ 支持集群模式,可以将多个 RabbitMQ 节点组成一个集群,从而提高系统的可靠性和可扩展性。
  • 高可用队列:RabbitMQ 提供镜像队列(Mirrored Queues),可以将队列的副本复制到集群中的其他节点,实现高可用性。
  • 联邦模式和分布式交换机:RabbitMQ 支持联邦模式(Federation)和分布式交换机(Shovel),可以在跨数据中心或广域网中同步消息。

优缺点

  • 优点:易于设置和管理,支持多种分布式模式,适用于中小规模的分布式系统。
  • 缺点:在高吞吐量和低延迟场景下性能可能不如 Kafka 和 RocketMQ。

ActiveMQ

分布式支持

  • 主从架构:ActiveMQ 支持主从架构,通过主从复制实现高可用性。当主节点故障时,从节点可以接管。
  • 网络连接器:ActiveMQ 支持网络连接器(Network of Brokers),允许将多个 ActiveMQ 节点连接在一起,实现消息的分布式传递和负载均衡。
  • 集群模式:支持通过共享文件系统或数据库实现集群部署。

优缺点

  • 优点:JMS 兼容性强,适用于企业级应用,支持多种分布式部署模式。
  • 缺点:集群管理和配置较复杂,性能在高吞吐量场景下可能不如 Kafka 和 RocketMQ。

RocketMQ

分布式支持

  • 多副本机制:RocketMQ 支持多副本机制,每个分区的消息可以复制到多个 Broker 上,提供高可用性和容错能力。
  • 水平扩展:RocketMQ 通过增加更多的 Broker 节点来扩展系统的容量和处理能力,适应业务增长。
  • 高可用性:支持主从架构,通过主从同步和异步刷盘机制实现高可用性。

优缺点

  • 优点:高吞吐量、低延迟,支持分布式事务,适用于金融、电商和实时数据处理等高性能需求的场景。
  • 缺点:学习曲线较陡,集群管理和运维需要一定的专业知识。

Kafka

分布式支持

  • 分区机制:Kafka 通过分区机制实现水平扩展,每个主题可以有多个分区,分区可以分布在不同的 Broker 上,实现负载均衡和高可用性。
  • 多副本机制:Kafka 支持多副本机制,每个分区的消息可以复制到多个 Broker 上,确保数据的高可用性和容错能力。
  • 数据保留策略:Kafka 支持数据持久化和保留策略,适用于大数据和实时数据流处理。

优缺点

  • 优点:高吞吐量、低延迟,强大的水平扩展能力,适用于大规模数据流处理和实时分析场景。
  • 缺点:学习曲线陡,管理和运维复杂,对硬件资源要求较高。

总结

这四种消息队列系统都支持分布式场景,但各有侧重:

  • RabbitMQ:适用于中小规模分布式系统,支持多种分布式模式,易于设置和管理。
  • ActiveMQ:适用于企业级应用,支持 JMS 兼容性和多种分布式部署模式,但集群管理较复杂。
  • RocketMQ:适用于需要高吞吐量、低延迟和分布式事务支持的场景,适合金融、电商和实时数据处理。
  • Kafka:适用于大规模数据流处理和实时分析场景,具有强大的水平扩展能力和高吞吐量、低延迟特性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值