源码研究RocketMQ主从同步机制(HA),顺利通过阿里Java岗面试


2.1 Master启动流程(HAService)

public void start() throws Exception {

this.acceptSocketService.beginAccept();

this.acceptSocketService.start();

this.groupTransferService.start();

this.haClient.start();

}

public void start() throws Exception {

this.acceptSocketService.beginAccept();

this.acceptSocketService.start();

this.groupTransferService.start();

this.haClient.start();

}

  • 建立HA服务端监听服务,处理客户Slave客户端监听请求。

  • 启动AcceptSocketService,处理监听逻辑。

  • 启动GroupTransferService线程。

  • 启动HA客户端线程。

不管是 Master 还是 Slave 都将按照上述流程启动,在内部的实现会根据 Broker 配置来决定真正开启的流程。

2.1.1 AcceptSocketService 实现原理

AcceptSocketService作为Master端监听Slave连接的实现类,作为HAService的内部类,其类图如图所示: 这里写图片描述

  • SocketAddress socketAddressListen:Broker服务监听套接字(本地IP+端口号)。

  • ServerSocketChannel serverSocketChannel:服务端Socket通道,基于NIO。

  • Selector selector:事件选择器,基于NIO。

HAService$AcceptSocketService#beginAccept

public void beginAccept() throws Exception {

this.serverSocketChannel = ServerSocketChannel.open();

this.selector = RemotingUtil.openSelector();

this.serverSocketChannel.socket().setReuseAddress(true);

this.serverSocketChannel.socket().bind(this.socketAddressListen);

this.serverSocketChannel.configureBlocking(false);

this.serverSocketChannel.register(this.selector, SelectionKey.OP_ACCEPT);

}

创建ServerSocketChannel、创建Selector、设置TCP reuseAddress、绑定监听端口、设置为非阻塞模式,并注册OP_ACCEPT(连接事件)。

HAService$AcceptSocketService#run

this.selector.select(1000);

Set selected = this.selector.selectedKeys();

if (selected != null) {

for (SelectionKey k : selected) {

if ((k.readyOps() & SelectionKey.OP_ACCEPT) != 0) {

SocketChannel sc = ((ServerSocketChannel) k.channel()).accept();

if (sc != null) {

HAService.log.info("HAService receive new connection, "+ sc.socket().getRemoteSocketAddress());

try {

HAConnection conn = new HAConnection(HAService.this, sc);

conn.start();

HAService.this.addConnection(conn);

} catch (Exception e) {

log.error(“new HAConnection exception”, e);

sc.close();

}

}

} else {

log.warn("Unexpected ops in select " + k.readyOps());

}

}

selected.clear();

}

该方法是标准的基于NIO的服务端程式实例,选择器每1s处理一次处理一次连接就绪事件。连接事件就绪后,调用ServerSocketChannel的accept()方法创建SocketChannel,与服务端数据传输的通道。然后为每一个连接创建一个HAConnection对象,该HAConnection将负责M-S数据同步逻辑。

2.1.2 GroupTransferService实现原理

GroupTransferService同步主从同步阻塞实现,如果是同步主从模式,消息发送者将消息刷写到磁盘后,需要继续等待新数据被传输到从服务器,从服务器数据的复制是在另外一个线程HAConnection中去拉取,所以消息发送者在这里需要等待数据传输的结果,GroupTransferService就是实现该功能,该类的整体结构与同步刷盘实现类(CommitLog$GroupCommitService)类似,本节只关注该类的核心业务逻辑doWaitTransfer的实现。

private void doWaitTransfer() {

synchronized (this.requestsRead) {

if (!this.requestsRea

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值