前一阵子刚整理完RocketMQ4.3.x版本的相关配置的工作,接下来就来测试一下改变参数会带来什么好的结果

首先我就选中了useEpollNativeSelector 这个参数

默认这个参数是 false

这个参数的意思就是是否启用Epoll IO模型。Linux环境建议开启


然后我就打开了这个参数试试看看会不会生效

首先是namesrv 弄了一个配置文件指向启动

RocketMQ4.3.X关于设置useEpollNativeSelector = true报错问题-LMLPHP

然后启动namesrv

sh bin/mqnamesrv -c conf/namesrv.conf

RocketMQ4.3.X关于设置useEpollNativeSelector = true报错问题-LMLPHP

很不幸抛出了一个异常

java.lang.IllegalStateException: incompatible event loop type: io.netty.channel.nio.NioEventLoop
at io.netty.channel.AbstractChannel$AbstractUnsafe.register(AbstractChannel.java:411)
at io.netty.channel.SingleThreadEventLoop.register(SingleThreadEventLoop.java:72)
at io.netty.channel.SingleThreadEventLoop.register(SingleThreadEventLoop.java:60)
at io.netty.channel.MultithreadEventLoopGroup.register(MultithreadEventLoopGroup.java:64)
at io.netty.bootstrap.AbstractBootstrap.initAndRegister(AbstractBootstrap.java:320)
at io.netty.bootstrap.AbstractBootstrap.doBind(AbstractBootstrap.java:271)
at io.netty.bootstrap.AbstractBootstrap.bind(AbstractBootstrap.java:235)
at org.apache.rocketmq.remoting.netty.NettyRemotingServer.start(NettyRemotingServer.java:212)
at org.apache.rocketmq.namesrv.NamesrvController.start(NamesrvController.java:156)
at org.apache.rocketmq.namesrv.NamesrvStartup.start(NamesrvStartup.java:154)
at org.apache.rocketmq.namesrv.NamesrvStartup.main0(NamesrvStartup.java:58)
at org.apache.rocketmq.namesrv.NamesrvStartup.main(NamesrvStartup.java:51)

通过抛出的异常追查一下源码

源码位置

发现在执行构造函数的时候初始化的是下面代码 90-143行

public NettyRemotingServer(final NettyServerConfig nettyServerConfig,
final ChannelEventListener channelEventListener) {
super(nettyServerConfig.getServerOnewaySemaphoreValue(), nettyServerConfig.getServerAsyncSemaphoreValue());
this.serverBootstrap = new ServerBootstrap();
this.nettyServerConfig = nettyServerConfig;
this.channelEventListener = channelEventListener; int publicThreadNums = nettyServerConfig.getServerCallbackExecutorThreads();
if (publicThreadNums <= 0) {
publicThreadNums = 4;
} this.publicExecutor = Executors.newFixedThreadPool(publicThreadNums, new ThreadFactory() {
private AtomicInteger threadIndex = new AtomicInteger(0); @Override
public Thread newThread(Runnable r) {
return new Thread(r, "NettyServerPublicExecutor_" + this.threadIndex.incrementAndGet());
}
}); this.eventLoopGroupBoss = new NioEventLoopGroup(1, new ThreadFactory() {
private AtomicInteger threadIndex = new AtomicInteger(0); @Override
public Thread newThread(Runnable r) {
return new Thread(r, String.format("NettyBoss_%d", this.threadIndex.incrementAndGet()));
}
}); if (useEpoll()) {
this.eventLoopGroupSelector = new EpollEventLoopGroup(nettyServerConfig.getServerSelectorThreads(), new ThreadFactory() {
private AtomicInteger threadIndex = new AtomicInteger(0);
private int threadTotal = nettyServerConfig.getServerSelectorThreads(); @Override
public Thread newThread(Runnable r) {
return new Thread(r, String.format("NettyServerEPOLLSelector_%d_%d", threadTotal, this.threadIndex.incrementAndGet()));
}
});
} else {
this.eventLoopGroupSelector = new NioEventLoopGroup(nettyServerConfig.getServerSelectorThreads(), new ThreadFactory() {
private AtomicInteger threadIndex = new AtomicInteger(0);
private int threadTotal = nettyServerConfig.getServerSelectorThreads(); @Override
public Thread newThread(Runnable r) {
return new Thread(r, String.format("NettyServerNIOSelector_%d_%d", threadTotal, this.threadIndex.incrementAndGet()));
}
});
} loadSslContext();
}

也就是说这里接收链接的线程池 eventLoopGroupBoss 永远都是 NioEventLoopGroup  如果设置了useEpollNativeSelector=true就会初始化EpollEventLoopGroup这个类处理请求

这样就会造成两种线程模型的不兼容状态

导致出现异常 java.lang.IllegalStateException: incompatible event loop type: io.netty.channel.nio.NioEventLoop


按常理说阿里的人不会出现这样的低级错误啊

回头又看了看github的bug列表果然有人提这个问题bug还是开启状态

RocketMQ4.3.X关于设置useEpollNativeSelector = true报错问题-LMLPHP

????为什么?

难道是我使用配置有问题吗?还是哪里理解有误那?知道的网友可以告诉我啊!!!!


最新消息我也提交了bug维护人员已经修改bug但是要等到4.4.1版本才可以修正

RocketMQ4.3.X关于设置useEpollNativeSelector = true报错问题-LMLPHP

RocketMQ4.3.X关于设置useEpollNativeSelector = true报错问题-LMLPHP

05-07 15:25