这节我们来分析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方法