Netty 从源码中了解 一
了解何为Netty
- 官网网站 : https://netty.io/
- Netty是一个NIO客户端服务器框架,可快速轻松地开发网络应用程序,例如协议服务器和客户端。它极大地简化和简化了网络编程,例如TCP和UDP套接字服务器。
1.Netty详解
了解Netty的第一步先从Netty的启动类开始接触
在了解EventLoopGroup
在了解EventLoop
在了解NioEventLoopGroup
在了解NioEventLoop
1.1 Netty的启动
Bootsrap,ServerBootstrap
1.1.1 Bootsrap
1.1.2 ServerBootstrap
@Override
public ServerBootstrap group(EventLoopGroup group) {
return group(group, group);
}
public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
// 调用的是父类的AbstactBootstrap的group
// 主要还是把 parentGroup的EventLoopGroup进行设置
super.group(parentGroup);
if (childGroup == null) {
throw new NullPointerException("childGroup");
}
if (this.childGroup != null) {
throw new IllegalStateException("childGroup set already");
}
this.childGroup = childGroup;
return this;
}
1.1.3 EventLoopGroup
Netty 的代码结构略微有点儿复杂,我们先通过类图对 EventLoop 有个基本认识。
- Netty 的任务调度框架还是遵循了 java.util.concurrent 中 Executor 的接口 Netty
任务调度框架的实现在 io.netty.util.concurrent 包中,其接口是 EventExecutor 和 - EventExecutorGroup。从命名可以看出任务调度是基于事件的。 io.netty.channel 包中
- EventLoopGroup 和 EventLoop 基于 io.netty.util.concurrent 封装了 channel
执行的业务逻辑
。
EventLoopGroup 一对多 EventLoop
EventLoop 一对多 Channel
ChannelFuture register(Channel var1);
ChannelFuture register(ChannelPromise var1);
EventLoopGroup的初始化核心逻辑
//
protected MultithreadEventExecutorGroup(int nThreads, Executor executor, EventExecutorChooserFactory chooserFactory, Object... args) {
this.terminatedChildren = new AtomicInteger();
this.terminationFuture = new DefaultPromise(GlobalEventExecutor.INSTANCE);
if (nThreads <= 0) {
throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads));
} else {
if (executor == null) {
executor = new ThreadPerTaskExecutor(this.newDefaultThreadFactory());
}
this.children = new EventExecutor[nThreads];
int j;
for(int i = 0; i < nThreads; ++i) {
boolean success = false;
boolean var18 = false;
try {
var18 = true;
this.children[i] = this.newChild((Executor)executor, args);
success = true;
var18 = false;
} catch (Exception var19) {
throw new IllegalStateException("failed to create a child event loop", var19);
} finally {
if (var18) {
if (!success) {
int j;
for(j = 0; j < i; ++j) {
this.children[j].shutdownGracefully();
}
for(j = 0; j < i; ++j) {
EventExecutor e = this.children[j];
try {
while(!e.isTerminated()) {
e.awaitTermination(2147483647L, TimeUnit.SECONDS);
}
} catch (InterruptedException var20) {
Thread.currentThread().interrupt();
break;
}
}
}
}
}
if (!success) {
for(j = 0; j < i; ++j) {
this.children[j].shutdownGracefully();
}
for(j = 0; j < i; ++j) {
EventExecutor e = this.children[j];
try {
while(!e.isTerminated()) {
e.awaitTermination(2147483647L, TimeUnit.SECONDS);
}
} catch (InterruptedException var22) {
Thread.currentThread().interrupt();
break;
}
}
}
}
this.chooser = chooserFactory.newChooser(this.children);
FutureListener<Object> terminationListener = new FutureListener<Object>() {
public void operationComplete(Future<Object> future) throws Exception {
if (MultithreadEventExecutorGroup.this.terminatedChildren.incrementAndGet() == MultithreadEventExecutorGroup.this.children.length) {
MultithreadEventExecutorGroup.this.terminationFuture.setSuccess((Object)null);
}
}
};
EventExecutor[] var24 = this.children;
j = var24.length;
for(int var26 = 0; var26 < j; ++var26) {
EventExecutor e = var24[var26];
e.terminationFuture().addListener(terminationListener);
}
Set<EventExecutor> childrenSet = new LinkedHashSet(this.children.length);
Collections.addAll(childrenSet, this.children);
this.readonlyChildren = Collections.unmodifiableSet(childrenSet);
}
}
核心: this.children[i] = this.newChild((Executor)executor, args);
对于NioEventLoopGroup的具体实现
protected EventLoop newChild(Executor executor, Object... args) throws Exception {
return new NioEventLoop(this, executor, (SelectorProvider)args[0], ((SelectStrategyFactory)args[1]).newSelectStrategy(), (RejectedExecutionHandler)args[2]);
}
this: NioEventLoopGroup的引入
executor: 默认情况下是 ThreadPerTaskExecutor
(SelectorProvider)args[0]:
从上文中看默认是ThreadPerTaskExecutor, 具体ThreadPerTaskExecutor起到何作用,后面会提及
if (executor == null) {
executor = new ThreadPerTaskExecutor(this.newDefaultThreadFactory());
}
((SelectStrategyFactory)args[1]).newSelectStrategy(): 故名思义,就是Select的 选择策略,下文会讲
**(RejectedExecutionHandler)args[2]:**控制任务的拒绝策略,默认为抛出 RejectedExecutionException
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;
final SelectorTuple selectorTuple = openSelector();
selector = selectorTuple.selector;
unwrappedSelector = selectorTuple.unwrappedSelector;
selectStrategy = strategy;
}
从此代码中可以看出,NioEventLoopGroup和EventLoopGroup的联系,strategy,rejectedExecutionHandler的具体用处 不细数,查看源码即可
final SelectorTuple selectorTuple = openSelector();
this.chooser = chooserFactory.newChooser(this.children);
提供了选择方案
// DefaultEventExecutorChooserFactory.class
@Override
public EventExecutorChooser newChooser(EventExecutor[] executors) {
if (isPowerOfTwo(executors.length)) {
return new PowerOfTwoEventExecutorChooser(executors);
} else {
return new GenericEventExecutorChooser(executors);
}
}
private static boolean isPowerOfTwo(int val) {
return (val & -val) == val;
}
private static final class PowerOfTwoEventExecutorChooser implements EventExecutorChooser {
private final AtomicInteger idx = new AtomicInteger();
private final EventExecutor[] executors;
PowerOfTwoEventExecutorChooser(EventExecutor[] executors) {
this.executors = executors;
}
@Override
public EventExecutor next() {
return executors[idx.getAndIncrement() & executors.length - 1];
}
}
channel 往 EventLoop 中进行注册
的核心逻辑
public class MultithreadEventLoopGroup extends MultithreadEventExecutorGroup implements EventLoopGroup{
// 调用父类的 next()方法
public EventLoop next() {
return (EventLoop)super.next();
}
public ChannelFuture register(Channel channel) {
return this.next().register(channel);
}
}
public abstract class MultithreadEventExecutorGroup extends AbstractEventExecutorGroup{
private final EventExecutorChooser chooser;
public EventExecutor next() {
return this.chooser.next();
}
}
1.1.4 ChannelHandler
在一篇中单独研究