选择器EventExecutorChooser

​在上一节NioEventLoop创建中, 我们提到了选择器EventExecurotChooser的创建. 这一节我们详细介绍下它.
我们从代码说起

io.netty.util.concurrent.DefaultEventExecutorChooserFactory#newChooser
public EventExecutorChooser newChooser(EventExecutor[] executors) {
    if (isPowerOfTwo(executors.length)) {
        return new PowerOfTwoEventExecutorChooser(executors);
    } else {
        return new GenericEventExecutorChooser(executors);
    }
}

从代码中我们看到, 其中executors就是我们创建的NioEventLoop数组. 根据数组长度是否是2^n创建不同的选择器.为啥要这样做呢?其实还是为了性能考虑,凡是可以提高性能的地方, Netty可是从不缺席.
选择器就是为了当有新连接进入时, 通过这个选择器选择一个NioEventLoop进行’服务’. 虽然创建了不同的选择器, 但是它们选择的思路的一样的, 就是从数组中循环选择.
比如NioEventLoop数组长度是8, 加入客户端连接到服务器之后, 服务器通过选择器EventExecutorChooser选择第一个NioEventLoop为其服务, 接着第二个客户端连接到服务器, 选择器EventExecutorChooser选择第二个NioEventLoop为其服务, 以此类推, 假如第八个客户端连接到服务器, 为其服务的是第八个NioEventLoop. 那么第九个客户端连接到服务器之后, 则又由第一个NioEventLoop为其服务了. 毕竟NioEventLoop封装的Selector是多路复用也就体现在此处.

只是选择器的两个实现类采取重复循环选择NioEventLoop的方式不同而已. 那么它们的不同之处在哪里呢? 我们通过代码说明

PowerOfTwoEventExecutorChooser(EventExecutor[] executors) {
    this.executors = executors;
}
@Override
public EventExecutor next() {
    return executors[idx.getAndIncrement() & executors.length - 1];
}
GenericEventExecutorChooser(EventExecutor[] executors) {
    this.executors = executors;
}
@Override
public EventExecutor next() {
    return executors[Math.abs(idx.getAndIncrement() % executors.length)];
}

其实简单说, 就是一个通过按位与(&)操作符, 另一个通过取模(%)运算符进行选取. 因此为了效率, 大部分情况下, 我们在设置NioEventLoop数组大小时, 使用2^n可以提高性能. 但是我查看了Dubbo和RocketMQ, 它们也有使用3的情况. 这个没有统一规范.

微信公众号

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值