BrokerController类初始化示意图

Broker的启动入口是,BrokerStartup的main方法,然后就创建了BrokerController(调用构造器),接下进入BrokerController的初始化方法(initialize方法)。

RocketMQ源码分析系列之六:Broker入口管理类——BrokerController_RocketMQ

BrokerController的构造器

在看构造器代码之前,我们先一起看一下类的成员变量,代码如下(本文的中文注释是我加的,如有问题欢迎指正)

/**
* 整个broker的配置,主要包括当前broker的名称、分组、是否master、历史内容的存储位置等
*/
private final BrokerConfig brokerConfig;
/**
* broker作为服务端启动nettyServer的配置
*/
private final NettyServerConfig nettyServerConfig;
/**
* broker作为客户端的NettyClient的配置
*/
private final NettyClientConfig nettyClientConfig;
/**
* 消息存储的核心配置,主要包括消息的存储位置、单个文件大小、内存刷盘频率等事关性能的配置
*/
private final MessageStoreConfig messageStoreConfig;
/**
* consumer端的消费offset的集中管理,主要的关系就是topic、group、queueId、offset
*/
private final ConsumerOffsetManager consumerOffsetManager;
/**
* consumer的管理和维护,提供consumer的注册,取消,关闭等,主要的关系是group,consumerGroupInfo
*/
private final ConsumerManager consumerManager;
/**
* consumer的过滤管理,针对consumer端的消息过滤,主要关系是topic,consumer,expression
*/
private final ConsumerFilterManager consumerFilterManager;
/**
* producer的管理和维护,提供producer的注册,取消,关闭等,主要关系是group,channel,ClientChannelInfo
*/
private final ProducerManager producerManager;
/**
* 基于netty的框架实现,主要监听客户端的网络操作,网络的链接、关闭、异常、空闲等事件操作
*/
private final ClientHousekeepingService clientHousekeepingService;
/**
* 针对consumer的请求拉取消息的事件处理,基于netty框架,解析并执行内部业务功能,最后将数据返回
*/
private final PullMessageProcessor pullMessageProcessor;
/**
* 针对客户端请求的服务保持,是java的Thread模式,主要是监听消息有新的时候通知客户端执行拉取操作
*/
private final PullRequestHoldService pullRequestHoldService;
/**
* 新消息到达的监听服务,联合PullRequestHostService进行消息到达的通知功能
*/
private final MessageArrivingListener messageArrivingListener;
/**
* broker对请求处理的封装类,处理对应的操作,主要有通知,重置,转换,状态等
*/
private final Broker2Client broker2Client;
/**
* 维护消费者组的一些附加信息,便于运维
*/
private final SubscriptionGroupManager subscriptionGroupManager;
/**
* 处理消费者组信息变更事件的监听器
*/
private final ConsumerIdsChangeListener consumerIdsChangeListener;
private final RebalanceLockManager rebalanceLockManager = new RebalanceLockManager();
/**
* broker请求外部的封装,主要是通过netty的底层通信完成和namesrv的交互
*/
private final BrokerOuterAPI brokerOuterAPI;
private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryImpl(
"BrokerControllerScheduledThread"));
/**
* salve的同步操作,如果broker是slave角色,执行同步操作,主要同步元数据信息
*/
private final SlaveSynchronize slaveSynchronize;
/**
* 以下是使用到的各种队列,主要是处理发送,拉取,查询等操作
*/
private final BlockingQueue<Runnable> sendThreadPoolQueue;
private final BlockingQueue<Runnable> putThreadPoolQueue;
private final BlockingQueue<Runnable> pullThreadPoolQueue;
private final BlockingQueue<Runnable> replyThreadPoolQueue;
private final BlockingQueue<Runnable> queryThreadPoolQueue;
private final BlockingQueue<Runnable> clientManagerThreadPoolQueue;
private final BlockingQueue<Runnable> heartbeatThreadPoolQueue;
private final BlockingQueue<Runnable> consumerManagerThreadPoolQueue;
private final BlockingQueue<Runnable> endTransactionThreadPoolQueue;
/**
* 基于shell的服务端过滤管理
*/
private final FilterServerManager filterServerManager;
/**
* broker的服务状态管理,实时记录broker的操作性能
*/
private final BrokerStatsManager brokerStatsManager;
private final List<SendMessageHook> sendMessageHookList = new ArrayList<SendMessageHook>();
private final List<ConsumeMessageHook> consumeMessageHookList = new ArrayList<ConsumeMessageHook>();
/**
* 消息的存储功能,核心及高性能的消息存储
*/
private MessageStore messageStore;
/**
* broker作为服务的nettyServer的启动
*/
private RemotingServer remotingServer;
/**
* broker的两级服务,一个是快速提供服务操作,只是没有pull的事件处理
*/
private RemotingServer fastRemotingServer;
/**
* topic的配置管理,主要提供根据topic获得对应的topic的配置信息,涉及读写队列数量、操作权限等
*/
private TopicConfigManager topicConfigManager;
/***********以下是使用到的各种线程池服务,和队列一一对应关系******************/
/**
* 发送消息线程池
*/
private ExecutorService sendMessageExecutor;
/**
* Broker向NameServer发送自己信息的线程池
*/
private ExecutorService putMessageFutureExecutor;
/**
* 拉取消息线程池
*/
private ExecutorService pullMessageExecutor;
/**
* 应答消息线程池
*/
private ExecutorService replyMessageExecutor;
/**
* 查询消息线程池
*/
private ExecutorService queryMessageExecutor;
/**
* admin的broker线程池
*/
private ExecutorService adminBrokerExecutor;
/**
* 客户端管理线程池
*/
private ExecutorService clientManageExecutor;
/**
* 心跳监测线程池
*/
private ExecutorService heartbeatExecutor;
/**
* consumer的管理线程池
*/
private ExecutorService consumerManageExecutor;
/**
* 执行事务提交或回滚的线程池
*/
private ExecutorService endTransactionExecutor;
/**
*
*/
private boolean updateMasterHAServerAddrPeriodically = false;
/**
* broker的各种操作预警的机制,主要有记录操作数量
*/
private BrokerStats brokerStats;
private InetSocketAddress storeHost;
/**
* broker的快速失败策略,主要针对系统的请求,开启开功能及时清理过期的请求,避免请求堆积
*/
private BrokerFastFailure brokerFastFailure;
private Configuration configuration;
/**
* 文件监听服务,如果netty提供ssl安全机制,则加载对应的安全key并执行安全机制
*/
private FileWatchService fileWatchService;
/**
* 针对事物消息的验证服务
*/
private TransactionalMessageCheckService transactionalMessageCheckService;
/**
* 事物消息服务,处理接受的内容是事物消息
*/
private TransactionalMessageService transactionalMessageService;

接下来我们看下BrokerController的构造器,构造器基于传入的四个配置信息(即BrokerConfigNettyServerConfigNettyClientConfigMessageStoreConfig),赋值给内部配置对象,然后初始化内部关联的对象,主要是consumer,producer等的初始化操作。代码如下:

public BrokerController(
final BrokerConfig brokerConfig,
final NettyServerConfig nettyServerConfig,
final NettyClientConfig nettyClientConfig,
final MessageStoreConfig messageStoreConfig
) {
this.brokerConfig = brokerConfig;
this.nettyServerConfig = nettyServerConfig;
this.nettyClientConfig = nettyClientConfig;
this.messageStoreConfig = messageStoreConfig;
//初始化消费端的offset管理器
this.consumerOffsetManager = messageStoreConfig.isEnableLmq() ? new LmqConsumerOffsetManager(this) : new ConsumerOffsetManager(this);
//初始化topic管理器
this.topicConfigManager = messageStoreConfig.isEnableLmq() ? new LmqTopicConfigManager(this) : new TopicConfigManager(this);
//初始化pull消息处理器
this.pullMessageProcessor = new PullMessageProcessor(this);
//初始化pull消息服务
this.pullRequestHoldService = messageStoreConfig.isEnableLmq() ? new LmqPullRequestHoldService(this) : new PullRequestHoldService(this);
//初始化消息到达后执行的监听器
this.messageArrivingListener = new NotifyMessageArrivingListener(this.pullRequestHoldService);
//初始化消费消息的id监听器
this.consumerIdsChangeListener = new DefaultConsumerIdsChangeListener(this);
//初始化消费者管理器
this.consumerManager = new ConsumerManager(this.consumerIdsChangeListener);
this.consumerFilterManager = new ConsumerFilterManager(this);
//初始化消息生产者管理器
this.producerManager = new ProducerManager();
//初始化监听客户端网络的监听器
this.clientHousekeepingService = new ClientHousekeepingService(this);
//初始化broker与客户端进行心跳监测的操作类
this.broker2Client = new Broker2Client(this);
//初始化订阅消息的管理器
this.subscriptionGroupManager = messageStoreConfig.isEnableLmq() ? new LmqSubscriptionGroupManager(this) : new SubscriptionGroupManager(this);
//初始化broker的接口服务管理,主要和name server交互
this.brokerOuterAPI = new BrokerOuterAPI(nettyClientConfig);
//初始化过滤器server管理器
this.filterServerManager = new FilterServerManager(this);
//主从同步管理,主要对slave有效,同步元数据
this.slaveSynchronize = new SlaveSynchronize(this);
//队列初始化
this.sendThreadPoolQueue = new LinkedBlockingQueue<Runnable>(this.brokerConfig.getSendThreadPoolQueueCapacity());
this.putThreadPoolQueue = new LinkedBlockingQueue<Runnable>(this.brokerConfig.getPutThreadPoolQueueCapacity());
this.pullThreadPoolQueue = new LinkedBlockingQueue<Runnable>(this.brokerConfig.getPullThreadPoolQueueCapacity());
this.replyThreadPoolQueue = new LinkedBlockingQueue<Runnable>(this.brokerConfig.getReplyThreadPoolQueueCapacity());
this.queryThreadPoolQueue = new LinkedBlockingQueue<Runnable>(this.brokerConfig.getQueryThreadPoolQueueCapacity());
this.clientManagerThreadPoolQueue = new LinkedBlockingQueue<Runnable>(this.brokerConfig.getClientManagerThreadPoolQueueCapacity());
this.consumerManagerThreadPoolQueue = new LinkedBlockingQueue<Runnable>(this.brokerConfig.getConsumerManagerThreadPoolQueueCapacity());
this.heartbeatThreadPoolQueue = new LinkedBlockingQueue<Runnable>(this.brokerConfig.getHeartbeatThreadPoolQueueCapacity());
this.endTransactionThreadPoolQueue = new LinkedBlockingQueue<Runnable>(this.brokerConfig.getEndTransactionPoolQueueCapacity());
//初始化当前broker的状态管理器
this.brokerStatsManager = messageStoreConfig.isEnableLmq() ? new LmqBrokerStatsManager(this.brokerConfig.getBrokerClusterName(), this.brokerConfig.isEnableDetailStat()) : new BrokerStatsManager(this.brokerConfig.getBrokerClusterName(), this.brokerConfig.isEnableDetailStat());

this.setStoreHost(new InetSocketAddress(this.getBrokerConfig().getBrokerIP1(), this.getNettyServerConfig().getListenPort()));
//快速失败策略
this.brokerFastFailure = new BrokerFastFailure(this);
this.configuration = new Configuration(
log,
BrokerPathConfigHelper.getBrokerConfigPath(),
this.brokerConfig, this.nettyServerConfig, this.nettyClientConfig, this.messageStoreConfig
);
}

BrokerController的初始化方法initialize

首先来总结下initialize方法的作用:

  • 加载历史的内容,历史内容都是存储到本地的文件中,主要是做消息接受,分发,过滤的管理内容加载
  • 加载消息存储内容,核心重要原生的消息读取
  • 构造netty的服务,当前作为broker的服务端
  • 各种执行消息操作的线程池配置,内部是基于各个功能做线程池隔离
  • 注册事件处理机制,特别说,这里注册时处理拉取消息以外的事件处理
  • 执行各种任务调度,主要是报告当前服务情况,保存基于消息的管理内容,和namesrv的数据交互
  • 基于高可用的master,salve的配置及输出
  • 执行事务,鉴权,hooks的操作
public boolean initialize() throws CloneNotSupportedException {
//从配置文件中加载topic的配置信息
boolean result = this.topicConfigManager.load();
//加载consumer的偏移量
result = result && this.consumerOffsetManager.load();
//加载订阅的分组
result = result && this.subscriptionGroupManager.load();
//加载consumer的过滤器
result = result && this.consumerFilterManager.load();

if (result) {
try {
//默认消息存储实现类
this.messageStore =
new DefaultMessageStore(this.messageStoreConfig, this.brokerStatsManager, this.messageArrivingListener,
this.brokerConfig);
if (messageStoreConfig.isEnableDLegerCommitLog()) {
DLedgerRoleChangeHandler roleChangeHandler = new DLedgerRoleChangeHandler(this, (DefaultMessageStore) messageStore);
((DLedgerCommitLog)((DefaultMessageStore) messageStore).getCommitLog()).getdLedgerServer().getdLedgerLeaderElector().addRoleChangeHandler(roleChangeHandler);
}
//borker的状态监控初始化
this.brokerStats = new BrokerStats((DefaultMessageStore) this.messageStore);
//load plugin
MessageStorePluginContext context = new MessageStorePluginContext(messageStoreConfig, brokerStatsManager, messageArrivingListener, brokerConfig);
this.messageStore = MessageStoreFactory.build(context, this.messageStore);
this.messageStore.getDispatcherList().addFirst(new CommitLogDispatcherCalcBitMap(this.brokerConfig, this.consumerFilterManager));
} catch (IOException e) {
result = false;
log.error("Failed to initialize", e);
}
}

//加载历史数据
result = result && this.messageStore.load();

if (result) {
//broker作为netty的server端
this.remotingServer = new NettyRemotingServer(this.nettyServerConfig, this.clientHousekeepingService);
NettyServerConfig fastConfig = (NettyServerConfig) this.nettyServerConfig.clone();
fastConfig.setListenPort(nettyServerConfig.getListenPort() - 2);
//快速服务端实现 —— broker的两级服务,一个是快速提供服务操作,只是没有pull的事件处理
this.fastRemotingServer = new NettyRemotingServer(fastConfig, this.clientHousekeepingService);
//初始化发送消息线程池
this.sendMessageExecutor = new BrokerFixedThreadPoolExecutor(
this.brokerConfig.getSendMessageThreadPoolNums(),
this.brokerConfig.getSendMessageThreadPoolNums(),
1000 * 60,
TimeUnit.MILLISECONDS,
this.sendThreadPoolQueue,
new ThreadFactoryImpl("SendMessageThread_"));
//初始化Broker向NameServer发送自己信息的线程池
this.putMessageFutureExecutor = new BrokerFixedThreadPoolExecutor(
this.brokerConfig.getPutMessageFutureThreadPoolNums(),
this.brokerConfig.getPutMessageFutureThreadPoolNums(),
1000 * 60,
TimeUnit.MILLISECONDS,
this.putThreadPoolQueue,
new ThreadFactoryImpl("PutMessageThread_"));
//初始化拉取消息线程池
this.pullMessageExecutor = new BrokerFixedThreadPoolExecutor(
this.brokerConfig.getPullMessageThreadPoolNums(),
this.brokerConfig.getPullMessageThreadPoolNums(),
1000 * 60,
TimeUnit.MILLISECONDS,
this.pullThreadPoolQueue,
new ThreadFactoryImpl("PullMessageThread_"));
//初始化应答消息线程池
this.replyMessageExecutor = new BrokerFixedThreadPoolExecutor(
this.brokerConfig.getProcessReplyMessageThreadPoolNums(),
this.brokerConfig.getProcessReplyMessageThreadPoolNums(),
1000 * 60,
TimeUnit.MILLISECONDS,
this.replyThreadPoolQueue,
new ThreadFactoryImpl("ProcessReplyMessageThread_"));
//初始化查询消息线程池
this.queryMessageExecutor = new BrokerFixedThreadPoolExecutor(
this.brokerConfig.getQueryMessageThreadPoolNums(),
this.brokerConfig.getQueryMessageThreadPoolNums(),
1000 * 60,
TimeUnit.MILLISECONDS,
this.queryThreadPoolQueue,
new ThreadFactoryImpl("QueryMessageThread_"));
//初始化admin的broker线程池
this.adminBrokerExecutor =
Executors.newFixedThreadPool(this.brokerConfig.getAdminBrokerThreadPoolNums(), new ThreadFactoryImpl(
"AdminBrokerThread_"));
//初始化客户端管理线程池
this.clientManageExecutor = new ThreadPoolExecutor(
this.brokerConfig.getClientManageThreadPoolNums(),
this.brokerConfig.getClientManageThreadPoolNums(),
1000 * 60,
TimeUnit.MILLISECONDS,
this.clientManagerThreadPoolQueue,
new ThreadFactoryImpl("ClientManageThread_"));
//初始化心跳监测线程池
this.heartbeatExecutor = new BrokerFixedThreadPoolExecutor(
this.brokerConfig.getHeartbeatThreadPoolNums(),
this.brokerConfig.getHeartbeatThreadPoolNums(),
1000 * 60,
TimeUnit.MILLISECONDS,
this.heartbeatThreadPoolQueue,
new ThreadFactoryImpl("HeartbeatThread_", true));
//初始化执行事务提交或回滚的线程池
this.endTransactionExecutor = new BrokerFixedThreadPoolExecutor(
this.brokerConfig.getEndTransactionThreadPoolNums(),
this.brokerConfig.getEndTransactionThreadPoolNums(),
1000 * 60,
TimeUnit.MILLISECONDS,
this.endTransactionThreadPoolQueue,
new ThreadFactoryImpl("EndTransactionThread_"));
//初始化consumer的管理线程池
this.consumerManageExecutor =
Executors.newFixedThreadPool(this.brokerConfig.getConsumerManageThreadPoolNums(), new ThreadFactoryImpl(
"ConsumerManageThread_"));
//注册事件处理机制及对应的实现类
this.registerProcessor();

final long initialDelay = UtilAll.computeNextMorningTimeMillis() - System.currentTimeMillis();
final long period = 1000 * 60 * 60 * 24;
//通过定时器定时记录broker的状态信息
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
BrokerController.this.getBrokerStats().record();
} catch (Throwable e) {
log.error("schedule record error.", e);
}
}
}, initialDelay, period, TimeUnit.MILLISECONDS);
//通过定时器定时持久化consumer的偏移量内容
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
BrokerController.this.consumerOffsetManager.persist();
} catch (Throwable e) {
log.error("schedule persist consumerOffset error.", e);
}
}
}, 1000 * 10, this.brokerConfig.getFlushConsumerOffsetInterval(), TimeUnit.MILLISECONDS);
//通过定时器定时持久化consumer的过滤器内容
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
BrokerController.this.consumerFilterManager.persist();
} catch (Throwable e) {
log.error("schedule persist consumer filter error.", e);
}
}
}, 1000 * 10, 1000 * 10, TimeUnit.MILLISECONDS);
//通过定时器定时执行broker的保护验证机制
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
BrokerController.this.protectBroker();
} catch (Throwable e) {
log.error("protectBroker error.", e);
}
}
}, 3, 3, TimeUnit.MINUTES);
//通过定时器定时打印各个配置的内容量
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
BrokerController.this.printWaterMark();
} catch (Throwable e) {
log.error("printWaterMark error.", e);
}
}
}, 10, 1, TimeUnit.SECONDS);
//通过定时器定时打印日志内容的大小
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
log.info("dispatch behind commit log {} bytes", BrokerController.this.getMessageStore().dispatchBehindBytes());
} catch (Throwable e) {
log.error("schedule dispatchBehindBytes error.", e);
}
}
}, 1000 * 10, 1000 * 60, TimeUnit.MILLISECONDS);

//name server的配置
if (this.brokerConfig.getNamesrvAddr() != null) {
//更新name server的配置
this.brokerOuterAPI.updateNameServerAddressList(this.brokerConfig.getNamesrvAddr());
log.info("Set user specified name server address: {}", this.brokerConfig.getNamesrvAddr());
} else if (this.brokerConfig.isFetchNamesrvAddrByAddressServer()) {
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {

@Override
public void run() {
try {
BrokerController.this.brokerOuterAPI.fetchNameServerAddr();
} catch (Throwable e) {
log.error("ScheduledTask fetchNameServerAddr exception", e);
}
}
}, 1000 * 10, 1000 * 60 * 2, TimeUnit.MILLISECONDS);
}

if (!messageStoreConfig.isEnableDLegerCommitLog()) {
if (BrokerRole.SLAVE == this.messageStoreConfig.getBrokerRole()) {
if (this.messageStoreConfig.getHaMasterAddress() != null && this.messageStoreConfig.getHaMasterAddress().length() >= 6) {
this.messageStore.updateHaMasterAddress(this.messageStoreConfig.getHaMasterAddress());
this.updateMasterHAServerAddrPeriodically = false;
} else {
this.updateMasterHAServerAddrPeriodically = true;
}
} else {
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
BrokerController.this.printMasterAndSlaveDiff();
} catch (Throwable e) {
log.error("schedule printMasterAndSlaveDiff error.", e);
}
}
}, 1000 * 10, 1000 * 60, TimeUnit.MILLISECONDS);
}
}

if (TlsSystemConfig.tlsMode != TlsMode.DISABLED) {
// Register a listener to reload SslContext
try {
fileWatchService = new FileWatchService(
new String[] {
TlsSystemConfig.tlsServerCertPath,
TlsSystemConfig.tlsServerKeyPath,
TlsSystemConfig.tlsServerTrustCertPath
},
new FileWatchService.Listener() {
boolean certChanged, keyChanged = false;

@Override
public void onChanged(String path) {
if (path.equals(TlsSystemConfig.tlsServerTrustCertPath)) {
log.info("The trust certificate changed, reload the ssl context");
reloadServerSslContext();
}
if (path.equals(TlsSystemConfig.tlsServerCertPath)) {
certChanged = true;
}
if (path.equals(TlsSystemConfig.tlsServerKeyPath)) {
keyChanged = true;
}
if (certChanged && keyChanged) {
log.info("The certificate and private key changed, reload the ssl context");
certChanged = keyChanged = false;
reloadServerSslContext();
}
}

private void reloadServerSslContext() {
((NettyRemotingServer) remotingServer).loadSslContext();
((NettyRemotingServer) fastRemotingServer).loadSslContext();
}
});
} catch (Exception e) {
log.warn("FileWatchService created error, can't load the certificate dynamically");
}
}
//初始化事物管理机制
initialTransaction();
//初始化命令行管理执行,执行操作的管控
initialAcl();
//初始化rcp的hook机制
initialRpcHooks();
}
return result;
}

结束

作为自己阅读源码的随记,不可避免存在问题和遗漏,欢迎指正错误和讨论。


原文在我的公众号“平凡的程序员”。

RocketMQ源码分析系列之六:Broker入口管理类——BrokerController_消息中间件_02