Netty源码解析(三) —— NioEventLoop初始化

这节我们来分析NioEventLoop的代码实现,还记得上节在NioEventLoopGroup中我们创建NioEventLoop,下面先看它的继承关系
这里写图片描述


构造方法

    /**
     * @param parent  NioEventLoopGroup
     * @param executor  线程执行器 每次调用会创建一个name为nioEventLoopGroup-2-1的FastThreadLocalThread
     * @param selectorProvider selector的provider
     * @param strategy
     * @param rejectedExecutionHandler
     */
    NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider,
                 SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler) {
        super(parent, executor, false, DEFAULT_MAX_PENDING_TASKS, rejectedExecutionHandler);
        if (selectorProvider == null) {
            throw new NullPointerException("selectorProvider");
        }
        if (strategy == null) {
            throw new NullPointerException("selectStrategy");
        }
        provider = selectorProvider;
        //创建一个selector的包装对象
        final SelectorTuple selectorTuple = openSelector();
        selector = selectorTuple.selector;
        unwrappedSelector = selectorTuple.unwrappedSelector;
        selectStrategy = strategy;
    }

SelectorTuple 代码

    private static final class SelectorTuple {
        final Selector unwrappedSelector;//原生的未包装的selector
        final Selector selector;//优化后的selector

        SelectorTuple(Selector unwrappedSelector) {
            this.unwrappedSelector = unwrappedSelector;
            this.selector = unwrappedSelector;
        }

        SelectorTuple(Selector unwrappedSelector, Selector selector) {
            this.unwrappedSelector = unwrappedSelector;
            this.selector = selector;
        }
    }

io.netty.channel.nio.NioEventLoop#openSelector创建一个selector,每个NioEventLoop对应一个selector

    /**
     * 打开selector  并且对selector内部的selectorKeys数据结构进行优化
     * @return
     */
    private SelectorTuple openSelector() {
        final Selector unwrappedSelector;
        try {
            //通过provider拿到一个原生的selector
            unwrappedSelector = provider.openSelector();
        } catch (IOException e) {
            throw new ChannelException("failed to open a new selector", e);
        }

        //不支持优化selector操作 直接返回原生的selector
        if (DISABLE_KEYSET_OPTIMIZATION) {
            return new SelectorTuple(unwrappedSelector);
        }

        //拿到sun.nio.ch.SelectorImpl 的字节码
        Object maybeSelectorImplClass = AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                try {
                    return Class.forName(
                            "sun.nio.ch.SelectorImpl",
                            false,
                            PlatformDependent.getSystemClassLoader());
                } catch (Throwable cause) {
                    return cause;
                }
            }
        });

        if (!(maybeSelectorImplClass instanceof Class) ||
                // ensure the current selector implementation is what we can instrument.
                !((Class<?>) maybeSelectorImplClass).isAssignableFrom(unwrappedSelector.getClass())) {
            if (maybeSelectorImplClass instanceof Throwable) {
                Throwable t = (Throwable) maybeSelectorImplClass;
                logger.trace("failed to instrument a special java.util.Set into: {}", unwrappedSelector, t);
            }
            //如果获取SelectorImpl字节码失败,则返回一个SelectorTuple未包装的原生selector
            return new SelectorTuple(unwrappedSelector);
        }

        //获取SelectorImpl字节码成功
        final Class<?> selectorImplClass = (Class<?>) maybeSelectorImplClass;
        final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();

        Object maybeException = AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                try {
                    /**
                     * 反射替换hashset和set成员变量为netty优化后的数组实现的set
                     * 优化的方案  用数组实现set集合  add添加的时间复杂度降低为O(1)
                     */
                    Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
                    Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");

                    Throwable cause = ReflectionUtil.trySetAccessible(selectedKeysField, true);
                    if (cause != null) {
                        return cause;
                    }
                    cause = ReflectionUtil.trySetAccessible(publicSelectedKeysField, true);
                    if (cause != null) {
                        return cause;
                    }

                    //反射替换
                    selectedKeysField.set(unwrappedSelector, selectedKeySet);
                    publicSelectedKeysField.set(unwrappedSelector, selectedKeySet);
                    return null;
                } catch (NoSuchFieldException e) {
                    return e;
                } catch (IllegalAccessException e) {
                    return e;
                }
            }
        });

        if (maybeException instanceof Exception) {
            selectedKeys = null;
            Exception e = (Exception) maybeException;
            logger.trace("failed to instrument a special java.util.Set into: {}", unwrappedSelector, e);
            //出现异常返回原生的selector
            return new SelectorTuple(unwrappedSelector);
        }
        //把selectedkey的引用传递给NioEventLoop的成员变量
        selectedKeys = selectedKeySet;
        logger.trace("instrumented a special java.util.Set into: {}", unwrappedSelector);
        //返回优化后的selector
        return new SelectorTuple(unwrappedSelector,
                                 new SelectedSelectionKeySetSelector(unwrappedSelector, selectedKeySet));
    }

这一部分主要是对系统的原生selector的优化,系统的selectoraccept read write事件接受SelectionKey是hashSet,selectedKeys 主要是有事件通知的时候向其中add

public abstract class SelectorImpl extends AbstractSelector {
    //保存的accept read write事件接受SelectionKey
    protected Set<SelectionKey> selectedKeys = new HashSet();
    protected HashSet<SelectionKey> keys = new HashSet();
    private Set<SelectionKey> publicKeys;
    private Set<SelectionKey> publicSelectedKeys;

而Netty的优化也是对selectedKeys 优化的反射替换成自己实现的selectedKeys

final class SelectedSelectionKeySet extends AbstractSet<SelectionKey> {

    SelectionKey[] keys;
    int size;

    SelectedSelectionKeySet() {
        keys = new SelectionKey[1024];
    }

    @Override
    public boolean add(SelectionKey o) {
        if (o == null) {
            return false;
        }

        keys[size++] = o;
        if (size == keys.length) {
            increaseCapacity();
        }

        return true;
    }

netty用一个数组实现的set集合,来把add的事件复杂度降到了O(1),虽然很小的一个细节,但是netty处处都体现着为性能考虑



下面介绍一下其他比较重要的方法
io.netty.channel.nio.NioEventLoop#rebuildSelector0重新构建selector,dk空轮训导致cpu占用100%的bug
io.netty.channel.nio.NioEventLoop#run启动服务 轮询selector
io.netty.channel.nio.NioEventLoop#processSelectedKeys处理SelectedKeys
io.netty.channel.nio.NioEventLoop#processSelectedKeysPlain处理没有优化的selectorKey
io.netty.channel.nio.NioEventLoop#processSelectedKeysOptimized处理优化后的selectorKey
io.netty.channel.nio.NioEventLoop#select轮询selector方法

猜你喜欢

转载自blog.csdn.net/u011702633/article/details/81948024