走进消息队列 | 青训营

80 阅读10分钟

一、消息队列的概念

保存消息的一个容器,本质是队列,需要支持高吞吐、高并发、高可用。

应用场景

1.应用解耦:

用户下单后,订单系统需要通知库存系统。传统的做法是,订单系统调用库存系统的接口。

image.png

传统模式的缺点:

1)假如库存系统无法访问,则订单减库存将失败,从而导致订单失败;

2)订单系统与库存系统耦合; 如何解决以上问题呢?引入应用消息队列后的方案,如下图: image.png

·订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。
·库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操作。
·假如:在下单时库存系统不能正常使用。也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。实现订单系统与库存系统的应用解耦。

2.流量削峰:

一般在秒杀或团抢活动中使用广泛。 秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。

  • 可以控制活动的人数;

  • 可以缓解短时间内高流量压垮应用; image.png 处理方式:

1)用户的请求,服务器接收后,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面;

2)秒杀业务根据消息队列中的请求信息,再做后续处理。

3.异步处理:

用户注册后,需要发注册邮件和注册短信。传统的做法有两种——串行方式、并行方式。

  • 串行方式:将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务全部完成后,返回给客户端。

image.png

  • 并行方式:将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成后,返回给客户端。

image.png

4.日志处理:

将消息队列用在日志处理中,比如Kafka的应用,解决大量日志传输的问题。结构简化如下: image.png

  • 日志采集客户端,负责日志数据采集,定时写受写入Kafka队列;
  • Kafka消息队列,负责日志数据的接收,存储和转发;
  • 日志处理应用:订阅并消费kafka队列中的日志数据;

5.消息通讯:

消息通讯是指,消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。比如实现点对点消息队列,或者聊天室等。

点对点通讯:客户端A和客户端B使用同一队列,进行消息通讯。 image.png

聊天室通讯:客户端A,客户端B,客户端N订阅同一主题,进行消息发布和接收,实现类似聊天室效果。

image.png

二、消息队列-Kafka

1、kafka使用场景:

Kafka是一个高性能、可扩展的分布式消息队列系统,适用于多种场景,包括但不限于以下情况:

业务日志:将系统产生的日志信息以事件流的方式进行收集和处理。
用户行为数据:实时收集和处理用户在应用中的行为数据,用于个性化推荐、统计分析等。
Metrics数据:监控和收集系统指标数据,用于性能评估、故障排查等。

2、基本概念:

  • Producer(生产者):向Kafka发送消息的客户端应用程序。
  • Cluster(集群):由多个Kafka broker组成的分布式系统。
  • Consumer(消费者):从Kafka订阅并接收消息的客户端应用程序。
  • Topic(主题):消息在Kafka中的分类,类似于一个队列或者一个主题。
  • Partition(分区):每个Topic可以分为多个分区,每个分区都是一个有序、不可变的消息队列。

3、数据迁移、Offset、Partition选主

  • 数据迁移:在Kafka中,数据是以分区的形式存储的,当需要对分区进行重新分布或扩容时,可以通过添加新的broker节点,并使用工具进行数据迁移和重新分配,保证数据的高可用和负载均衡。
  • Offset(偏移量):Kafka使用Offset来标识消息在分区中的位置。每个消费者都会维护一个消费的Offset,表示下一条待消费的消息的位置。Kafka可以根据Offset来保证消息的顺序和可靠性。
  • Partition选主:在Kafka集群中,每个分区都有一个Leader节点和多个Follower节点。Leader负责处理读写请求,而Follower则复制Leader的数据。当Leader节点宕机或不可用时,Kafka会自动从Follower节点中选举出新的Leader,确保分区的高可用性。

4、一条消息从生产到消费要经过以下步骤:

  • Producer端逻辑:Producer创建一个消息并将其发送到指定的Topic和分区。Producer可以选择同步或异步方式发送消息,并可以设置发送消息的压缩、批量等参数。
  • Broker端逻辑:Kafka broker接收到Producer发送的消息后,将其写入对应Topic的分区中,并返回一个消息的Offset作为确认。
  • Consumer端逻辑:Consumer通过订阅Topic来拉取消息。Consumer可以按照固定的频率轮询Broker获取新的消息,并以Offset为依据,确保消费的消息是有序的。Consumer可以单独或以群组的方式进行消费,实现消息的负载均衡和高可用。

通过这样的处理流程,Kafka保证了消息在生产和消费过程中的可靠性、扩展性和高吞吐量。同时,Kafka还提供了许多配置选项和监控工具,帮助用户优化和管理整个消息处理流程。

三、消息队列-BMQ

1.Kafka在使用中遇到问题

  • 存储容量限制:Kafka的数据存储依赖于硬盘,当硬盘空间有限时,可能导致无法写入更多数据。
  • 吞吐量瓶颈:如果Producer和Consumer的速度不匹配,可能导致消息队列堆积或无法及时消费。
  • 数据可靠性:当Kafka的副本数量较低或网络故障时,可能导致数据丢失或不可用。
  • 配置复杂性:Kafka的配置参数较多,需要根据实际需求进行调优和管理。

2.BMQ架构

BMQ(BigMQ)是由阿里巴巴开发的一种分布式消息队列系统,旨在解决Kafka在大规模部署场景下的一些问题。BMQ的架构包括以下组件:

  • Broker:类似于Kafka的Broker,负责消息的存储、转发和管理。
  • Proxy:作为中间层,接收来自Producer和Consumer的请求,并将其路由到对应的Broker节点。
  • HDFS:BMQ使用HDFS作为底层存储,提供高可靠性和扩展性。
  • MetaStorage:用于存储和管理BMQ集群的元数据信息,如Topic的配置、Broker的状态等。

3.BMQ各模块的工作方式:

  • Broker:负责接收和存储消息,按照Topic和Partition进行分组和管理。Broker会将消息持久化到HDFS,并提供读写服务给Proxy。
  • Proxy:作为中间层,接收来自Producer和Consumer的请求,并根据元数据信息进行路由转发。Proxy还会对消息进行压缩和批处理,以提高传输效率。
  • HDFS:作为底层存储,负责持久化消息数据。BMQ使用HDFS的可靠性和容量来解决Kafka在大规模场景下可能遇到的存储容量限制问题。
  • MetaStorage:用于存储BMQ集群的元数据信息,包括Topic的配置、分区的状态等。MetaStorage可使用MySQL等数据库进行存储,以保证元数据的可靠性和一致性。

4.BMQ多机房容灾:

BMQ多机房容灾机制,主要通过以下方式实现:

  • 跨机房复制:BMQ可以将消息数据进行跨机房复制,以实现数据的备份和容灾。当一个机房不可用时,其他机房仍然可以提供服务。
  • 跨机房订阅:BMQ允许消费者在多个机房进行订阅,以实现消费者的容灾和负载均衡。
  • 选举机制:BMQ使用选举机制来选择主Broker和副本Broker,确保在机房故障时能够迅速切换并恢复服务。

通过以上机制,BMQ可以提供跨机房的高可用性和容灾能力,保证消息队列系统的可靠性和稳定性。

四、消息队列-RocketMQ

1.RocketMQ使用场景

  • 异步消息传递:RocketMQ能够提供高吞吐量和低延迟的消息传递,适合实时性要求不高、异步处理的场景。
  • 顺序消息处理:RocketMQ支持按照消息的顺序进行投递和消费,适用于需要保证消息处理顺序的业务场景。
  • 大规模分布式系统:RocketMQ提供了分布式部署、水平扩展和高可用性等特性,适用于大规模分布式系统的消息通信需求。

2.RocketMQ和Kafka对比

  • 存储方式:RocketMQ将消息存储在磁盘中,而Kafka将消息存储在磁盘和内存中。
  • 消息顺序保证:RocketMQ天生支持严格的消息顺序保证,而Kafka只能保证在单个分区内的顺序。
  • 分布式事务:RocketMQ提供了与分布式事务相关的功能,而Kafka则需要依赖外部系统来实现分布式事务。
  • 扩展性:Kafka具有更好的扩展性和横向扩展能力,能够支持更高的消息吞吐量。
  • 生态系统:Kafka具有更丰富的生态系统和成熟的工具库,而RocketMQ相对较小但也在不断发展壮大。

3.RocketMQ架构介绍

  • Producer(生产者):负责发送消息到Broker集群,可以将消息发送到指定的Topic和队列。
  • Broker(消息服务器):存储消息并处理消息的读写请求,负责消息的持久化和高可用性。
  • Nameserver(命名服务):提供了Topic的路由信息,Producer和Consumer通过查询Nameserver获取Broker的地址信息。
  • Consumer(消费者):订阅特定的Topic,并消费Broker推送的消息。

4.一条消息从生产到消费经过以下步骤:

  • Producer端逻辑:Producer创建消息并发送到指定的Topic和队列。Producer可以选择同步或异步方式发送消息,可以设置消息的延迟和批量发送等参数。
  • Broker端逻辑:Broker接收到Producer发送的消息后,将其存储在磁盘上,并返回一个消息的唯一标识(Message ID)作为确认。
  • Consumer端逻辑:Consumer通过订阅特定的Topic和队列来消费消息。Consumer通过向Nameserver查询Topic的路由信息,得到对应的Broker地址。之后,Consumer会从Broker拉取消息或注册一个回调函数来接收Broker推送的消息。