基本概念
主题(topic)
表示一类消息的集合,每个主题包含若干条消息,每条消息只能属于一个主题,是RocketMQ进行消息订阅的基本单位
一个生产者可以同时发送多种Topic的消息,而一个消费者只能对某种特定的Topic感兴趣,即只能订阅和消费一种Topic的消息
标签(tag)
为消息设置的标签,用于同一主题下区分不同类型的消息,来自同一个业务单元的消息,可以根据不同的业务目的在同一主题下设置不同的标签,标签能够有效的保持代码的清晰度和连贯性,并优化RocketMQ提供的查询系统。消费者可以根据tag实现对不同子主题的不同消费逻辑,实现更好的扩展性。
队列
存储消息的物理实体,一个Topic中可以包含多个Queue,每个Queue中存放的就是Topic的消息,一个Topic的Queue也被称为一个Topic中的消息分区。注意,一个Topic的Queue中的消息只能被一个消费者组中的一个消费者消费,一个Queue中的消息不允许同一个消费组中的多个消费者同时消费
消息的标识(messageID/key)
RocketMQ中的每个消息拥有一个唯一的messageID,且可以携带具有业务员标识的key,以方便对消息的查询。需要注意的是messageID有两个,在生产者send消息的时候会自动生成一个messageID,当消息到达Broker后,Broker也会自动生成一个messageID
Producer
消息的生产者,负责生产消息。Producer通过MQ的负载均衡模块选择相应的Broker集群队列进行消息投递,投递过程支持快速失败并且低延迟。RocketMQ中的消息生产者都是以生产者组的形式出现的,生产者组是同一类生产者的集合,这类Producer发送相同Topic类型的消息。一个生产者组可以同时发送多个主题的消息
Consumer
消息消费者,负责消费消息,一个消息消费者会从Broker服务器中获取消息,并对消息进行相关业务处理。RocketMQ中的消息消费者可以消费者组的形式出现,消息消费者组是一类消费者的集合,这类Consumer消费的是同一个Topic类型的消息。消费者组使得在消息消费方面,实现负载均衡(Queue的负载均衡)和容错(一个Consumer挂了,该Consumer group下其他的consumer可以接着消费原consumer消费的queue)目标变得非常容易。
注意:消费者组中的consumer的数量应该小于等于订阅Topic的Queue的数量,如果超出Queue的数量,则多出的consumer将不能消费消息
Name Server
NameServer是一个Broker与Topic路由的注册中心,支持Broker的动态注册与发现。
主要包含两个功能
- Broker管理:接受Broker集群的注册信息并且保存下来作为路由信息的基本数据;提供心跳监测机制,检查Broker是否还存活
- 路由信息管理:每个NameServer 中都保存着Broker集群的整个路由信息和用于客户端查询的队列信息。Producer和Consumer通过NameServer可以获取整个Broker集群的路由信息,从而进行消息的投递和消费。
路由注册
NameServer 通常是以集群的方式部署,不过NameServer 是无状态的,即NameServer 集群中的各个节点是无差异的,各个节点间相互不进行通信。各个节点之间是通过Broker节点启动时,轮询NameServer 列表,与每个NameServer 节点建立长连接,发起注册请求,在NameServer 内部维护着一个Broker列表,用来动态的存储Broker的信息
Broker节点为了证明自己是活着的,为了维护与NameServer间的长连接,会将最新的信息以心跳包的方式上报给NameServer,每30s发送一次心跳,心跳包中包含BrokerId,Broker地址,Broker名称,Broker所属的集群名称等。NameServer 在接收到心跳包后,会更新心跳的时间戳,记录这个Broker的最新存活时间。
路由剔除
由于Broker关机,宕机或者网络抖动等原因,NameServer 没有收到Broker的心跳,NameServer 可能会将其从Broker中剔除。
NameServer 中有一个定时任务,每隔10s就会扫描一次Broker表,查看每一个Broker的最新心跳时间戳,当距离当前时间超过120s,则会判定Broker失效。
路由发现
RocketMQ的路由发现采用的是Pull模型,当Topic路由信息发生变化的时候,NameServer 不会主动推送给客户端,而是客户端定时拉取主题最新的路由。默认客户端每隔30s会拉取一次最新的路由信息。
- push模型:推送模型,是一个发布-订阅模型,实时性较好,需要维护一个长连接,该模型适合实时性较高的场景,client数量不多。
- pull模型,拉取模型,存在实时性较差的问题
- long Polling模型:长轮询模型
客户端NameServer 选择策略
客户端在配置是必须写上NameServer 集群的地址,name客户端到底链接的是哪个NameServer 节点呢,客户端首先会先选一个随机数,然后再与NameServer 节点数量取模,此时得到的就是所要链接的节点索引,然后就会进行链接,如果链接失败,则会采用轮询的策略,逐个尝试其他的连接点。