RocketMq源码解析(6)

本文深入剖析RocketMq的第六部分,关注Netty网络配置,包括BrokerController、NettyServerConfig和NettyClientConfig的设置。同时,探讨消息存储配置,讲解BrokerController和MessageStoreConfig如何影响RocketMq的功能,如日志恢复和主从一致性。
摘要由CSDN通过智能技术生成

RocketMq源码解析(六)


这一期还是一些主要的配置文件,知道这些文件才能方便后续分析架构时知道整个系统设计的目的,主要分析都已在代码块

Netty网络配置

BrokerController

/**
     * 1 Netty服务配置
     *
     */
    private final NettyServerConfig nettyServerConfig;
    private final NettyClientConfig nettyClientConfig;

NettyServerConfig

public class NettyServerConfig implements Cloneable {
    /**
     * 1 监听端口
     * 2 Netty业务线程池线程个数
     * 3 Netty服务异步回调线程池线程数量
     * 4 Netty Selector线程个数
     * 5 控制单向的信号量
     * 6 控制异步的信号量
     * 7 服务空闲心跳检测 单位 秒
     * 8 Netty系统中 发送缓冲区的大小 65535 byte == 64 m
     * 9 Netty系统中 接受缓冲区的大小 65535 byte == 64 m
     * 10 是否开启缓存
     * 11 是否启用E_poll IO模型。Linux环境建议开启
     */
    private int listenePort=8888;
    private int serverWorkerThread=8;
    private int serverCallbackExecutorThreads=0;
    private int serverSelectorThreads=3;
    private int serverOneWaySemaphoreValue=256;
    private int serverAsyncSemaphoreValue = 64;
    private int serverChannelMaxIdleTimeSeconds = 120;

    private int serverSocketSndBufSzie=NettySystemConfig.socketSndbufSize;
    private int serverSocketRcvBufSize = NettySystemConfig.socketRcvbufSize;
    private boolean serverPooledByteBufAllocatorEnable = true;
    private boolean useEpollNativeSelector = false;

NettyClientConfig

public class NettyClientConfig {
    /**
     * 1 客户端工作的线程个数
     * 2 客户端异步回调线程数 默认为处理器的核数
     * 3 客户端单步信号量的值默认为 65535 64M
     * 4 客户端异步调用信号量的值 默认 65536 64M
     * 5 超时时间 单位毫秒
     * 6 连接不在响应时间 1分钟
     */
    private int clientWorkerThreads=4;
    private int clientCallbackExecutorThreads= Runtime.getRuntime().availableProcessors();
    private int clientOneWaySemaphoreValue=NettySystemConfig.CLIENT_ONEWAY_SEMAPHORE_VALUE;
    private int clientAsyncSemaphoreValue = NettySystemConfig.CLIENT_ASYNC_SEMAPHORE_VALUE;
    private int connectTimeoutMillis = 3000;
    private long channelNotActiveInterval = 1000 * 60;
    /**
     * 1 客户端通道最大空闲时间 120s
     * 2 客户端发送缓冲区的大小 65535 byte == 64 m
     * 3 客户端接受缓冲区的大小 65535 byte == 64 m
     * 4 客户端启用缓冲池分配器
     * 5 客户端是否超时关闭socket连接。
     */
    private int clientChannelMaxIdleTimeSeconds = 120;
    private int clientSocketSndBufSize = NettySystemConfig.socketSndbufSize;
    private int clientSocketRcvBufSize = NettySystemConfig.socketRcvbufSize;
    private boolean clientPooledByteBufAllocatorEnable = false;
    private boolean clientCloseSocketIfTimeout = false;

消息存储配置

BrokerController

private final MessageStoreConfig messageStoreConfig;

MessageStoreConfig

//日志保存的根目录
    @ImportantField
    private String storePathRootDir = System.getProperty("user.home") + File.separator + "store";
    //提交日志的目录
    @ImportantField
    private String storePathCommitLog = System.getProperty("user.home") + File.separator + "store" + File.separator + "commitlog";
    //提交日志的大小,默认1g
    private int mapedFileSizeCommitLog = 1024 * 1024 * 1024;
    //消费者队列大小,默认30w个
    private int mapedFileSizeConsumeQueue = 300000 * ConsumeQueue.CQ_STORE_UNIT_SIZE;

    //提交日志持久化的时间间隔 单位ms
    @ImportantField
    private int flushIntervalCommitLog = 500;
    //只在事务存储池开启时使用,提交数据至文件通道
    @ImportantField
    private int ccommitIntervalCommitLog = 200;
    //消息存储到commitlog文件时获取锁类型,如果为true使用ReentrantLock否则使用自旋锁
    private boolean useReentrantLockWhenPutMessage = false;
    //是否刷新提交日志计划,默认为实时
    @ImportantField
    private boolean flushCommitLogTimed = false;
    //ConsumeQueue刷新间隔
    private int flushIntervalConsumeQueue = 1000;
    // 回收(清除)资源间隔
    private int cleanResourceInterval = 10000;
    //CommitLog删除间隔
    private int deleteCommitLogFilesInterval = 100;
    /**
     * 1 删除consumequeue文件时间间隔
     * 2 销毁MappedFile被拒绝的最大存活时间,默认120s。清除过期文件线程在初次销毁mappedfile时,
     * 如果该文件被其他线程引用,引用次数大于0.则设置MappedFile的可用状态为false,
     * 并设置第一次删除时间,下一次清理任务到达时,如果系统时间大于初次删除时间加上本参数
     * 则将ref次数一次减1000,知道引用次数小于0,则释放物理资源
     * 3 重试删除文件间隔,配合destorymapedfileintervalforcibly
     */
    private int deleteConsumeQueueFileInterval = 100;
    private int destroyMapedFileIntervalForcibly = 1000 * 120;
    private int redeleteHangedFileInterval = 1000 * 120;
    /**
     * 1 默认删除时间 4am
     * 2 commitlog目录所在分区的最大使用比例,如果commitlog目录所在的分区使用比例大于该值,
     * 则触发过期文件删除
     */
    @ImportantField
    private String deleteWhen = "04";
    private int diskMaxUsedSpaceRatio = 75;
    //删除一个文件前至少保存的时间 默认72小时
    @ImportantField
    private int fileReservedTime = 72;
    //ConsumeQueue的流控制
    private int putMsgIndexHightWater = 600000;
    //单个消息最大容量 默认4MB
    private int maxMessageSize = 1024 * 1024 * 4;
    //恢复时是否CRC效验
    private boolean checkCRCOnRecover = true;
    /**
     * 1 写入commitLog需要多少页
     * 2 将数据提交到文件时要提交多少页
     * 3 磁盘在预热状态时至少写入的页数 默认4096
     */
    private int flushCommitLogLeastPages = 4;
    private int commitCommitLogLeastPages = 4;
    private int flushLeastPagesWhenWarmMapedFile = 1024 / 4 * 16;
    /**
     * 1 ConsumeQueue写入至少需要页的数量,默认2页,
     * 2 commitlog两次写入磁盘的最大间隔,如果超过该间隔,将fushCommitLogLeastPages要求直接写入磁盘操作
     * 3 Commitlog两次提交的最大间隔,如果超过该间隔,将直接提交
     * 4 Consume两次写入的最大间隔,如果超过该间隔,将忽略
     */
    // How many pages are to be flushed when flush ConsumeQueue
    private int flushConsumeQueueLeastPages = 2;
    private int flushCommitLogThoroughInterval = 1000 * 10;
    private int commitCommitLogThoroughInterval = 200;
    private int flushConsumeQueueThoroughInterval = 1000 * 60;
    //一次服务消息端消息拉取,消息在内存中传输允许的最大传输字节数默认256kb
    @ImportantField
    private int maxTransferBytesOnMessageInMemory = 1024 * 256;
    //一次服务消息拉取,消息在内存中传输运行的最大消息条数,默认为32条
    @ImportantField
    private int maxTransferCountOnMessageInMemory = 32;
    @ImportantField
    private int maxTransferBytesOnMessageInDisk = 1024 * 64;
    @ImportantField
    private int maxTransferCountOnMessageInDisk = 8;
    //访问消息在内存中比率,默认为40
    @ImportantField
    private int accessMessageInMemoryMaxRadio = 40;
    /**
     * 1 是否支持消息索引
     * 2 单个索引文件hash槽的个数,默认为五百万
     * 3 单个索引文件索引条目的个数,默认为两千万
     * 4 一次查询消息最大返回消息条数,默认64条
     */
    @ImportantField
    private boolean messageIndexEnable = true;
    private int maxHashSlotNum = 5000000;
    private int maxIndexNum = 5000000 * 4;
    private int maxMsgsNumBatch = 64;
    /**
     * 1 消息索引是否安全,默认为 false,文件恢复时选择文件检测点(commitlog.consumeque)的最小的与文件最后更新对比
     * 如果为true,文件恢复时选择文件检测点保存的索引更新时间作为对比
     * 2 Master监听端口,从服务器连接该端口,默认为10912
     * 3 Master与Slave心跳包发送间隔
     * 4 Master与save长连接空闲时间,超过该时间将关闭连接
     * 5 一次HA主从同步传输的最大字节长度,默认为32K
     */
    @ImportantField
    private boolean messageIndexSafe = false;
    private int haListenPort = 10912;
    private int haSendHeartbeatInterval = 1000 * 5;
    private int haHousekeepingInterval = 1000 * 20;
    private int haTransferBatchSize = 1024 * 32;
    /**
     * 1 Master服务器IP地址与端口号
     * 2 允许从服务器落户的最大偏移字节数,默认为256M。超过该值则表示该Slave不可用
     */
    @ImportantField
    private String haMasterAddress = null;
    private int haSlaveFallbehindMax = 1024 * 1024 * 256;
    @ImportantField
    private BrokerRole brokerRole = BrokerRole.ASYNC_MASTER;
    /**
     * 1 刷盘方式,默认为 ASYNC_FLUSH(异步刷盘),可选值SYNC_FLUSH(同步刷盘)
     * 2 同步刷盘超时时间
     * 3 延迟队列等级(s=秒,m=分,h=小时)
     * 4 延迟队列拉取进度刷盘间隔。默认10s
     */
    @ImportantField
    private FlushDiskType flushDiskType = FlushDiskType.ASYNC_FLUSH;
    private int syncFlushTimeout = 1000 * 5;
    private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h";
    private long flushDelayOffsetInterval = 1000 * 10;
    /**
     * 1 是否支持强行删除过期文件
     * 2 是否温和(?)地使用 MappedFile如果为true,将不强制将内存映射文件锁定在内存中
     * 3 从服务器是否坚持 offset检测
     * 4 是否支持 PutMessage Lock锁打印信息
     * 5 是否允许重复复制,默认为 false
     * 6 是否统计磁盘的使用情况,默认为true
     */
    @ImportantField
    private boolean cleanFileForciblyEnable = true;
    private boolean warmMapedFileEnable = false;
    private boolean offsetCheckInSlave = false;
    private boolean debugLockEnable = false;
    private boolean duplicationEnable = false;
    private boolean diskFallRecorded = true;
    /**
     * 1 putMessage锁占用超过该时间,表示 PageCache忙
     * 2 查询消息默认返回条数,默认为32
     */
    private long osPageCacheBusyTimeOutMills = 1000;
    private int defaultQueryMaxNum = 32;
    /**
     * 1 Commitlog是否开启 transientStorePool机制,默认为 false
     * 2 transientStorePool中缓存 ByteBuffer个数,默认5个
     * 3 从 transientStorepool中获取 ByteBuffer是否支持fail-fast
     */
    @ImportantField
    private boolean transientStorePoolEnable = false;
    private int transientStorePoolSize = 5;
    private boolean fastFailIfNoBufferInStorePool = false;

同样这一期也是默认没有写入get和set方法,看完这几个配置文件,大概也能知道整个Broker的更多功能和一些优化手段比如日志恢复,主从一致性等等,具体实现就要到具体的类中了。

RocketMQ NameServer 是 RocketMQ 的一个核心组件,主要负责管理 RocketMQ 集群中的各个 Broker 节点的信息,包括 Broker 的名称、IP 地址、状态等信息。在 RocketMQ 集群中,所有的 Broker 都需要向 NameServer 注册,以便 NameServer 能够掌握整个集群的状态信息。 RocketMQ NameServer 的源码位于 `rocketmq-namesrv` 模块中,其主要实现了以下功能: 1. 启动时加载配置文件,包括监听端口、存储路径、集群名称等信息; 2. 处理 Broker 节点的注册、注销请求,维护 Broker 节点的状态信息; 3. 处理 Consumer 节点的心跳请求,维护 Consumer 节点的状态信息; 4. 处理 Topic 的创建、删除请求,维护 Topic 的状态信息; 5. 提供查询 Broker 节点、Topic 等信息的接口。 RocketMQ NameServer 的核心类是 `NamesrvController`,它继承了 Netty 的 `NettyRemotingServer` 类,并实现了 `RequestProcessor` 接口,用于处理来自 Broker 和 Consumer 节点的请求。在 `NamesrvController` 中,还包含了 `RouteInfoManager`、`BrokerHousekeepingService`、`KVConfigManager` 等组件,用于维护集群状态信息和管理配置文件。 RocketMQ NameServer 的启动入口是 `main` 方法,它会加载配置文件并启动 `NamesrvController`。启动后,NameServer 会监听指定端口,等待来自 Broker 和 Consumer 节点的请求,并根据请求类型调用相应的处理方法进行处理。 总之,RocketMQ NameServer 的主要作用是管理整个 RocketMQ 集群的状态信息,确保集群中各个节点的状态始终保持同步。其源码实现比较复杂,需要深入理解 RocketMQ 的设计思想和架构原理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值