目录
一、介绍
MQ全称Message Queue,即消息队列,是一种应用间的通信方式,可用于分布式系统、异步处理等场景。在近一步去了解MQ之前,我们要清楚异步和同步的概念。
同步(Synchronization):同步是指一个进程在执行某个请求时,如果该请求需要一段时间才能返回信息,那么这个进程会一直等待下去,直到收到返回信息才继续执行下去。
这种方式按照预定的顺序执行,且可能会长时间等待某个操作的完成,有一个流程节点执行失败则全部失败。如下图所示,支付服务的请求成功与否,取决于用户、交易、通知和积分服务的执行状况,有一个失败则全部失败,但本质上支付服务的成功与否是不应该依赖于通知、积分等服务的执行结果。
同步调用的优势
1. 时效性强,等待到结果后才返回
同步调用的劣势
1. 拓展性差
2. 性能下降
3. 级联失败问题
异步(Asynchronization):异步是指进程不需要一直等待下去,而是继续执行下面的操作,不管其他进程的状态。当有信息返回的时候会通知进程进行处理,这样可以提高执行的效率。另外由于一个进程服务的执行成功与否不依赖于另外进程服务执行的结果,所以就不会有及联失败的问题。如下图所示,支付服务执行成功与否,只依赖于同步执行的用户服务,其他服务我们可以通过发送消息到消息队列(即消息代理)来通知其他服务去异步执行,因为从正常业务角度来讲,积分、通知这些服务即使执行失败也不应该影响支付服务,且这些服务对实效性要求也不高。
异步调用的优势
1. 解除耦合
2. 拓展性强
3. 无需等待
4. 性能好
5. 故障隔离
6. 缓存消息,流量削峰填谷
异步调用的劣势
1. 不能立即得到调用结果
2. 时效性差
3. 不确定下游业务执行是否成功
4. 业务安全依赖于Broker的可靠性
MQ(消息队列)通过它的异步机制,能够帮助我们在实际项目中,解决流量消峰、应用解耦、异步处理和消息分发等。MQ在流量消峰方面的作用非常显著。在高峰期,如果直接处理大量请求可能会导致系统崩溃。通过使用消息队列,可以将请求暂时存储起来,逐步处理,从而避免系统因瞬间大量请求而崩溃。例如,订单系统在高峰期可以处理一万次订单,但当订单量超过这个数量时,使用消息队列可以将订单分散处理,提升用户体验。
其次,MQ在应用解耦方面的作用也非常重要。在复杂的系统中,各个子系统之间的耦合会导致一旦某个环节出现问题,整个系统都会受到影响。通过使用消息队列,可以将各个子系统解耦,例如订单系统、库存系统、物流系统和支付系统之间通过消息队列进行通信,任何一个子系统的故障都不会影响到其他系统的正常运行12。
此外,MQ在异步处理方面的作用也非常明显。在一些业务场景中,某些操作不需要即时返回结果,例如用户注册后发送邮件和短信通知。通过消息队列,这些操作可以异步进行,加快主流程的响应时间。用户注册时,主流程可以快速返回注册成功的消息,而邮件和短信的通知则由消息队列异步处理。
最后,MQ在消息分发方面的作用也非常重要。在分布式系统中,多个系统可能需要对同一消息进行处理。通过消息队列,可以将消息分发给多个系统处理,提高系统的效率和可靠性。例如,付款成功后,付款系统可以将消息发送到消息队列,其他需要处理该消息的系统订阅该消息,从而实现对消息的分发和处理。
二、MQ技术选型
在选择消息队列(MQ)时,需要考虑的核心因素包括系统的吞吐量、可靠性、可用性、扩展性以及与现有技术的兼容性。 根据这些因素,以下几种消息队列系统在性能和适用场景上有各自的优势和劣势,ActiveMQ由于它的性能可靠性等各方面都比较差,在实际项目中我们通常是不会使用:
1. RabbitMQ:
特点:RabbitMQ是一个轻量级的消息队列系统,部署和使用都非常简单。
适用场景:适合对性能要求不是特别高,但需要易用性和灵活性的场景。
缺点:在大量消息堆积时,性能会急剧下降;使用小众语言Erlang开发,扩展和二次开发维护成本较高。
2. RocketMQ:
特点:由阿里开发,侧重于消息的顺序投递,具有高吞吐量和可靠性。
适用场景:适合处理高吞吐量的在线业务场景,如交易系统中的订单处理。
缺点:与周边生态系统的集成和兼容程度略逊于其他系统。
3. Kafka:
特点:Kafka是一个成熟的消息队列产品,支持高可靠性和稳定性。
适用场景:适合处理大量数据,适用于需要高吞吐量和容错性的场景。
缺点:单机超过64个队列/分区时,负载会明显增加,响应时间延长;适用于批量处理,同步收发消息的响应时延较高。
4. AMQP协议:
特点:AMQP是一种应用层的协议,用于消息队列的开放标准协议。
适用场景:适用于需要高度标准化的消息传递系统,支持多种消息队列产品。
优点:提供了生产者、消费者、交换机、队列等标准概念,便于系统间的通信和集成。
选择合适的消息队列系统时,应根据具体需求评估各个系统的特性,选择最适合项目需求的系统。例如,如果项目需要高吞吐量和容错性,Kafka可能是一个好的选择;而如果需要与现有生态系统高度集成,对消息的可靠性要求比较高,RocketMQ或RabbitMQ可能更合适。