RocketMQ基础篇-角色介绍

一、看前提问:

  1. RocketMQ有哪些角色?
  2. 各角色的作用?

二、角色一览图:
在这里插入图片描述
三、NameServer:
管理broker,集群中的各个服务都需要通过NameServer来了解各个服务的状态

  • 服务发现机制:
    请求发出时客户端通过注册中心获取所有的服务实例,客户端接着负载均衡算法选择可用的服务实例中的一个发送。
    在这里插入图片描述
    2.使用NameServer的原因:
    相比zk的强一致性,nameserver只需要保持最终一致性即可。

    NameServer如何保证最终数据一致性
    NameServer节点并不互相通信,但为保持最终数据一致性需要从路由注册、路由剔除、路由发现三个角度介绍:
    路由注册:
    对比zk强一致性,数据只需要写入主节点内部会通过状态机将数据复制到其他节点,ns节点之间无法通信,RocketMQ的策略是broker启动时轮训NameServer列表与每个NameServer节点建立长链接,发起注册请求。NameServer内部会维护一个Borker表用来动态存储Borker的信息。
    Broker会每隔30s向NameServer发送心跳包,包括BrokerId、Broker地址、Broker名称、Broker所属集群名称、队列和brokerIP对应关系等,然后NameServer接收到⼼跳包后,会更新时间戳,记录这个Broker的最新存活时间。Nameserver在处理心跳包时因多个Broker同时操作同一张Borker表,路由注册操作引入了ReadWriteLock读写锁,这个设计亮点允许多个消息⽣产者并发读,保证了消息发送时的⾼并发,但是同⼀时刻NameServer只能处理⼀个Broker⼼跳包,多个⼼跳包串⾏处理。这也是读写锁的经典使⽤场景,即读多写少。
    路由剔除:
    正常情况:Broker关闭,断开与NameServer长链接,Netty通道关闭监听器会监听到断开事件,然后将Broker剔除。
    异常情况:NameServer定时任务会每隔10s扫描一次Broker表将Broker最新时间戳与当前时间超过120s的也会进行剔除
    特殊情况:通过命令行工具禁止这个Broker的写权限,发送消息到这个Broker都会收到NO_PERMISSION响应,也会被剔除。
    路由发现:
    路由发现是客户端行为

  • 生产者:发送第一条消息根据topic从NameServer获取路由信息;

  • 消费者:启动时拉取
    RocketMQ也提供了定时拉取Topic最新路由信息的机制源码可以看:

DefaultMQProducer、DefaultMQConsumer都继承了MQClientInstance其中有个startScheduledTask,定时从NameServer获取最新的路由表,默认是30s

3.客户端NameServer选择策略:
客户端每次都会尝试从缓存的路由表获取Topic路由信息,找不到才会从NameServer更新。
选择策略:
RocketMQ会将用户设置的NameServer列表设置到NettyRemotingClient类的namesrvAddrList
字段中,如下:

private final AtomicReference<List<String>> namesrvAddrList = new
AtomicReference<List<String>>();

具体选择哪个NameServer使用round-robin策略,注意如果选择了NameServer节点后面也会优先选择这个节点除非发生异常情况,才会选择其它节点。主要是为了减少每个NameServer节点的压⼒,所以每
个客户端节点只随机与其中⼀个NameServer节点建⽴连接。为了保证NameServer集群每个节点的负载均衡,在round-robin策略时,每个客户端的初始位置都不同,如下:

# 其中initValueIndex就是计算一个随机值
private final AtomicInteger namesrvIndex = new AtomicInteger(initValueIndex());

之后每次选择NameServer时,namesrvIndex +1之后再对namesrvAddrList取模,计算在数据下标的位置,尝试创建连接,⼀旦创建成功,会将当前选择的NameServer地址记录到namesrvAddrChoosed字段中:

private final AtomicReference<String> namesrvAddrChoosed = new
AtomicReference<String>();

4.优点:

  • nameserver 互相独⽴,彼此没有通信关系,单台 nameserver 挂掉,不影响其他
  • nameserver 不会有频繁的读写,所以性能开销⾮常⼩,稳定性很⾼。
    四、Broker:
    提供消息的接受、存储、拉取等功能。
    在这里插入图片描述
    五、Producer:
    生产者
    在这里插入图片描述
    六、Consumer:
    消费者,Consumer会与NameServer建立长连接,每隔30s会从NameServer服务器查询topic路由信息,再根据ip映射文件从broker中消费消息并存入本地缓存。

七、Topic:
每一个topic代表一类消息,一个生产者可以发消息给一个或多个topic,一个消费者也可以订阅一个或多个topic。
八、Queue:
RokcetMQ都是磁盘消息队列模式,同一个消费组,一个分区只能由一个消费者来消费消息。
**Message Queue:**相当于是Topic的分区;⽤于并⾏发送和接收消息
RocketMQ 在进⾏Topic分⽚以后,已经达到⽔平扩展的⽬的了,为什么还需要进⼀步切分为Queue呢?
Queue 存在的意义: 消费负载均衡过程中资源分配的基本单元.
queue数量指定方式:

  • 代码指定:producer.setDefaultTopicQueueNums(8);
  • 配置⽂件指定:同时设置broker服务器的配置⽂件broker.properties:defaultTopicQueueNums=16
  • mqadmin命令创建:updateTopic -r/w(读写队列个数建议相等) 个数
    九、 Producer Group:
    生产者组
    十、Consumer Group:
    消费者组
    十一、Message:
    代表一条消息,必须指定一个topic,用户在发送时可设置messagekey便于查询,Message还可选Tag设置也可以添加额外的键值对。
    十二、Tag:
    标签可以被认为是对 Topic 进⼀步细化,相当于topic的二级消息分类。
    十三、Offset:
    Offset是指某个 Topic下的⼀条消息在某个 Message Queue⾥的 位置,offset主要分为本地文件类型和Broker代存类型两种。
    **集群消费模式:**由Broker端存储和控制offset(RemoteBrokerOffsetStore 结构)。
    **广播消费模式:**由LocalfileOffsetStore,把 Offset存到本地
    DefaultMQPushConsumer类中setConsumeFromWhere可以设置从哪儿开始消费(支持具体的offset和时间段)注意设置读取位置不是每次都有效,它的优先级默认在 Offset Store后面时读取不到Offset 的时候, ConsumeFromWhere 的设置才⽣效⼤部分情况下这个设置在 Consumer Group初次启动时有效。 如果 Consumer正常运⾏后被停⽌,然后再启动, 会接着上次的 Offset开始消费, ConsumeFromWhere 的设置无效。
    RocketMQ的broker端中,offset的是以json的形式持久化到磁盘⽂件中,⽂件路径为
    ${user.home}/store/config/consumerOffset.json
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值