掘金 后端 ( ) • 2024-04-14 11:04

highlight: a11y-dark theme: yu

RocketMQ在国内系统中使用还是比较多的,面试中,工作中常常被提及,以前有逐帧阅读过RocketMQ的源码,长时间不回顾,也忘得差不多了。这次就再拾起来重新回顾一番,也算加深下印象。

首先呢,RocketMQ是一款开源的分布式消息中间件,最初由阿里巴巴公司开发并开源。它提供了高可靠、高吞吐量、低延迟的消息传输服务,被广泛应用于大规模分布式系统中的消息通信场景。

RocketMQ包含以下几个核心组件:

  • Name Server
  • Broker
  • Producer
  • Consumer
  • Topic
  • Message Queue
  • Consumer Group

本文我们就从一个快递中心的角度,一起去看看Name Server所包含的功能以及工作原理。

Name Server负责维护整个RocketMQ集群中各个Broker的路由信息,客户端通过与Name Server交互获取消息发送或者消费的路由信息。

下面详细解释一下Name Server的功能:

路由注册

当一个Broker启动时,它会向Name Server注册自己的信息,包括Broker的名称、IP地址、监听端口等。Name Server会将这些信息记录下来,并在需要时向其他组件提供。

那么路由注册是如何进行的呢?

1. Broker启动时注册

当一个Broker启动时,它会向集群中的所有Name Server发送注册请求。这个注册请求包含了Broker的基本信息,如Broker名称、IP地址、监听端口等。

就好比一个快递公司的总部。每个快递员上班打卡,向总部发送自己上班了的信息。发送的信息就包含了自己的名字,工号,以及所在的位置。

2. Name Server接收注册请求

Name Server接收到Broker的注册请求后,会将该Broker的信息记录下来,并在自身的路由表中维护该Broker的路由信息。

总部接收到信息之后,就把该快递员的信息记录下来。

3. 路由信息更新

如果一个Broker发生了变化,比如新增了一个Broker节点、删除了一个Broker节点或者修改了Broker的配置信息,那么该Broker会重新向Name Server发送注册请求,告知Name Server发生了变化。Name Server接收到变化后会更新自身的路由表,保证路由信息的实时性和准确性。

总部会不断的更新快递员的信息,若是有新的快递员上班了,会增加信息。若是有快递员下班了,无法继续送货了就取消该快递员的信息,所以,总部的信息一直是实时的和最新的。

4. 心跳检测

Broker会定期向已注册的Name Server发送心跳请求,提交并更新自己的信息,Name Server可以据此检测Broker的状态是否正常。如果某个Broker长时间未响应心跳请求,Name Server会将其标记为不可用,并从路由信息中移除,以保证客户端获取到的路由信息是最新的和可用的。

快递员需要每隔一段时间向总部发信息上报自己的工作状态,若是长时间没发送信息,那么就认为这个快递员偷懒了,或不能继续工作了,处于离线状态,就不会给他安排新的活了。

5. 路由信息的提供

客户端在需要与Broker通信时,通过与Name Server交互获取路由信息。Name Server会根据客户端的请求,提供相应的路由信息,包括Broker的地址和端口等。客户端可以根据路由信息选择合适的Broker进行通信。

若是有客户想发快递了。会在官网找到总部,然后提交自己想把快递发到哪里,然后总部会找到符合条件的快递员。进行发货。

路由查询

客户端(包括生产者和消费者)需要与Broker通信时,首先要获取Broker的路由信息,以确定消息应该发送到哪个Broker或者从哪个Broker消费消息。客户端通过与Name Server交互,可以获取到所需的Broker信息,包括该Broker所在的地址和端口等。

那么路由查询具体如何执行的呢?

1. 客户端发送路由查询请求

客户端在需要与Broker通信时,首先向集群中的任意一个Name Server发送路由查询请求。查询请求中通常包含了客户端所需操作的主题(Topic)信息。

客户想找快递员时发快递的时候,会在官网找相关信息。同时会提交自己想寄快递的"主题",可以理解为种类。

1. Name Server接收路由查询请求

当一个Name Server接收到路由查询请求后,会根据请求中的主题信息,在自身维护的路由表中查找与该主题相关的Broker的路由信息。

这时候,总部的客服会看到客户的请求,根据货物的种类,找相关的快递员。

2. 路由信息响应

如果Name Server找到了与请求主题相关的Broker的路由信息,它会将这些路由信息打包成响应,发送给客户端。路由信息中包括了每个Broker的名称、地址、端口等信息。

找到相关的快递员之后,会把这个快递员的信息,比电话,名字,现在在哪,如何联系等都给客户发过去。

3. 客户端获取路由信息

客户端接收到Name Server的响应后,获取到了与请求主题相关的Broker的路由信息。根据这些路由信息,客户端可以选择合适的Broker进行通信。

客户收到快递员的信息之后,就可以主动联系快递员了。

4. 负载均衡和容错处理

客户端在获取到路由信息后,通常会根据一定的负载均衡策略选择一个Broker进行通信。同时,客户端也会实施一些容错机制,如当选择的Broker不可用时,会尝试选择其他可用的Broker进行通信。

一般在相同的条件下,会有多个快递员在工作,总部会根据工作情况返回,若是客户挑选的恰好在忙或者没有接电话,进行反馈,那么客户会选择其他的快递员进行投递。

心跳检测

Name Server会定期向已注册的Broker发送心跳请求,以检测Broker的状态是否正常。如果某个Broker长时间未响应心跳请求,Name Server会将其标记为不可用,并从路由信息中移除,以保证客户端获取到的路由信息是最新的和可用的。

1. Broker注册时发送心跳

当一个Broker启动并向Name Server注册时,它会定期(通常是每隔一定时间间隔)向所有已知的Name Server发送心跳消息。

上面说了,快递员需要每隔一段时间,向总部发送信息,汇报自己的工作情况。

2. 心跳消息格式

心跳消息通常包含了Broker的基本信息,比如Broker名称、IP地址、监听端口等。这些信息用于让Name Server确认Broker的存在和可用性。

信息一般包含快递员的基本信息,名字,在哪,工号等。

3. Name Server接收心跳消息

当一个Name Server接收到Broker发送的心跳消息后,会更新自己维护的Broker信息表,标记该Broker为在线状态,并记录下最近收到心跳的时间。

总部接收到信息之后,就维护一下所有上班的快递员表,标记这个快递员是上班了的,并记录了接收到信息的时间。

4. 超时检测

Name Server会定期检查维护的Broker信息表,判断哪些Broker已经超过了一定的时间没有发送心跳消息。如果发现某个Broker已经长时间未发送心跳消息,则认为该Broker可能已经宕机或者不可用。

总部的员工每隔一段时间,就把所有员工的表检查一遍,看看有没有快递员,很长时间没有汇报自己的信息,若是发现有快递员超过多久(真正的RocketMQ中是15秒)没有发送信息,那么就认为这个快递员离线了,不干活了。

5. 处理超时Broker

当发现某个Broker已经超时未发送心跳消息时,Name Server会将其标记为离线状态,并从维护的Broker信息表中移除该Broker的信息。同时,Name Server会将这一信息广播给集群中的其他Name Server,以确保整个集群中都能及时更新Broker的状态。

总部的员工一旦检查出来哪个快递员不干活了,还会告诉其他总部的员工,这家伙不干活了。别给他派活了。

6. 更新路由信息

当有Broker的状态发生变化时,Name Server会相应地更新维护的路由信息表。这样,客户端在获取路由信息时可以获得最新的、可用的Broker列表。

总部的这张快递员状态表,是实时更新的,确保客户在想寄快递的时候,能拿到最准确的最可靠的快递员的信息。

总结一下

也就是说通过路由信息的维护和查询,Name Server实现了Broker集群的动态扩展和节点的动态发现,使得RocketMQ集群具备了高可用性和灵活性。客户端通过与Name Server交互,可以快速地获取到消息发送和消费的路由信息,从而实现消息的可靠传输和高效处理。