AbstractBootstrap#initAndRegister
public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C extends Channel> implements Cloneable {
//初始化并注册
final ChannelFuture initAndRegister() {
Channel channel = null;
try {
//bootstrap.channel(NioServerSocketChannel.class)
//通过反射创建NioServerSocketChannel 注意NioServerSocketChannel的构造方法
//channelFactory=new ReflectiveChannelFactory ---> constructor=NioServerSocketChannel.class.getConstructor();
//channel=NioServerSocketChannel
//ReflectiveChannelFactory
channel = channelFactory.newChannel();//==>关注NioServerSocketChannel
//初始化
init(channel);
} catch (Throwable t) {
if (channel != null) {
// channel can be null if newChannel crashed (eg SocketException("too many open files"))
channel.unsafe().closeForcibly();
// as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor
return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t);
}
// as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor
return new DefaultChannelPromise(new FailedChannel(), GlobalEventExecutor.INSTANCE).setFailure(t);
}
//config().group()==bossGroup ===》 EventLoopGroup bossGroup=new NioEventLoopGroup(1);
//register开启了事件轮询线程
//config().group() boosGroup
//MultithreadEventLoopGroup.register()
ChannelFuture regFuture = config().group().register(channel);
if (regFuture.cause() != null) {
if (channel.isRegistered()) {
channel.close();
} else {
channel.unsafe().closeForcibly();
}
}
return regFuture;
}
}
上篇文章介绍到创建服务端channel和初始化,这篇主要介绍config().group().register(channel)注册流程。
1 MultithreadEventLoopGroup#register
MultithreadEventLoopGroup#register()
public abstract class MultithreadEventLoopGroup extends MultithreadEventExecutorGroup implements EventLoopGroup {
public ChannelFuture register(Channel channel) {
//channel= NioServerSocketChannel | NioSocketChannel
// next()=NioEventLoop
//SingleThreadEventLoop.register()
//从事件循环组选择一个NioEventLoop
return next().register(channel);
}
public EventLoop next() {
return (EventLoop) super.next();
}
}
MultithreadEventExecutorGroup#next
public abstract class MultithreadEventExecutorGroup extends AbstractEventExecutorGroup {
public EventExecutor next() {
//chooser=GenericEventExecutorChooser/PowerOfTwoEventExecutorChooser
//从executors对象数组中返回new NioEventLoop()对象
return chooser.next();
}
}
SingleThreadEventLoop#register()
public abstract class SingleThreadEventLoop extends SingleThreadEventExecutor implements EventLoop {
public ChannelFuture register(Channel channel) {
//channel= NioServerSocketChannel | NioSocketChannel
//调用重载方法
return register(new DefaultChannelPromise(channel, this));
}
public ChannelFuture register(final ChannelPromise promise) {
ObjectUtil.checkNotNull(promise, "promise");
//promise=DefaultChannelPromise
//promise.channel()= NioServerSocketChannel | NioSocketChannel
//promise.channel().unsafe() = AbstractUnsafe
//AbstractUnsafe.register
promise.channel().unsafe().register(this, promise);
return promise;
}
}
2 AbstractUnsafe#register
AbstractUnsafe#register
protected abstract class AbstractUnsafe implements Unsafe {
public final void register(EventLoop eventLoop, final ChannelPromise promise) {
if (eventLoop == null) {
throw new NullPointerException("eventLoop");
}
if (isRegistered()) {
promise.setFailure(new IllegalStateException("registered to an event loop already"));
return;
}
if (!isCompatible(eventLoop)) {
promise.setFailure(
new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName()));
return;
}
//promise=DefaultChannelPromise
//eventLoop=SingleThreadEventLoop
//this.eventLoop=NioEventLoop==>SingleThreadEventLoop.this
AbstractChannel.this.eventLoop = eventLoop;
//他们最终都调用了register0 eventLoop.inEventLoop()的作用? 判断当前线程 是不是 nioEventLoop绑定的那个线程
//AbstractEventExecutor.inEventLoop
if (eventLoop.inEventLoop()) { //此时为false
register0(promise);
} else {
try {
//SingleThreadEventExecutor.execute:将任务添加到队列 并尝试启动当前eventloop绑定的线程
// 2.1 启动NioEventLoop绑定的线程
eventLoop.execute(new Runnable() {
@Override
public void run() {
System.out.println("register0");
// 2.2 AbstractUnsafe.register0()
register0(promise);
}
});
} catch (Throwable t) {
logger.warn(
"Force-closing a channel whose registration task was not accepted by an event loop: {}",
AbstractChannel.this, t);
closeForcibly();
closeFuture.setClosed();
safeSetFailure(promise, t);
}
}
}
}
2.1 启动NioEventLoop绑定的线程
SingleThreadEventExecutor#execute
将任务添加到队列 并尝试启动当前eventloop绑定的线程
public abstract class SingleThreadEventExecutor extends AbstractScheduledEventExecutor implements OrderedEventExecutor {
public void execute(Runnable task) {
System.out.println("ccccccccccc");
if (task == null) {
throw new NullPointerException("task");
}
//调用doStartThread方法启动事件轮询后此方法返回true
boolean inEventLoop = inEventLoop();
//将任务加入线程队列
addTask(task);
//判断当前执行此任务的线程是否是SingleThreadEventExecutor
if (!inEventLoop) {
//启动当前eventloop绑定的线程
startThread();
if (isShutdown()) {
boolean reject = false;
try {
if (removeTask(task)) {
reject = true;
}
} catch (UnsupportedOperationException e) {
// The task queue does not support removal so the best thing we can do is to just move on and
// hope we will be able to pick-up the task before its completely terminated.
// In worst case we will log on termination.
}
if (reject) {
reject();
}
}
}
/**
* 如果添加任务到队列了 就唤醒事件循环的阻塞的selector
* addTaskWakesUp:false
*/
if (!addTaskWakesUp && wakesUpForTask(task)) {
//唤醒阻塞的selectT
//NioEventLoop.wakeup
wakeup(inEventLoop);
}
}
private void startThread() {
if (state == ST_NOT_STARTED) {
//尝试将ST_NOT_STARTED设置为ST_STARTED
if (STATE_UPDATER.compareAndSet(this, ST_NOT_STARTED, ST_STARTED)) {
boolean success = false;
try {
//真正启动线程
doStartThread();
success = true;
} finally {
//如果执行doStartThread()出现异常 将STATE_UPDATER.compareAndSet(this, ST_NOT_STARTED, ST_STARTED回滚
if (!success) {
STATE_UPDATER.compareAndSet(this, ST_STARTED, ST_NOT_STARTED);
}
}
}
}
}
}
SingleThreadEventExecutor#doStartThread
public abstract class SingleThreadEventExecutor extends AbstractScheduledEventExecutor implements OrderedEventExecutor {
/***
* 由ThreadPerTaskExecutor.execute创建
*/
private volatile Thread thread;
private void doStartThread() {
assert thread == null;
//真正的启动线程
//executor是一个lambda表达式 在当前类的构造方法里初始化的
//lambda表达式里会调用ThreadPerTaskExecutor.execute ==> 使用线程工厂创建线程
//最后执行lambda表达式的是线程工厂新创建的线程 lambda表达式中会把新创建的线程保存到thread变量 即绑定到NioEventLoop
//ThreadPerTaskExecutor.execute
executor.execute(new Runnable() {
@Override
public void run() {
//executor.execute()会创建一个线程
// 因此当前这个匿名内部类是在这个新线程里运行的
// 将新创建线程保存起来 绑定到当前nioeventloop
thread = Thread.currentThread();
if (interrupted) {
thread.interrupt();
}
boolean success = false;
updateLastExecutionTime();
try {
//NioEventLoop.run 事件循环
//重点 这个后面会单独介绍
SingleThreadEventExecutor.this.run();
success = true;
} catch (Throwable t) {
logger.warn("Unexpected exception from an event executor: ", t);
} finally {
for (;;) {
int oldState = state;
if (oldState >= ST_SHUTTING_DOWN || STATE_UPDATER.compareAndSet(
SingleThreadEventExecutor.this, oldState, ST_SHUTTING_DOWN)) {
break;
}
}
// Check if confirmShutdown() was called at the end of the loop.
if (success && gracefulShutdownStartTime == 0) {
if (logger.isErrorEnabled()) {
logger.error("Buggy " + EventExecutor.class.getSimpleName() + " implementation; " +
SingleThreadEventExecutor.class.getSimpleName() + ".confirmShutdown() must " +
"be called before run() implementation terminates.");
}
}
try {
// Run all remaining tasks and shutdown hooks.
for (;;) {
if (confirmShutdown()) {
break;
}
}
} finally {
try {
cleanup();
} finally {
// Lets remove all FastThreadLocals for the Thread as we are about to terminate and notify
// the future. The user may block on the future and once it unblocks the JVM may terminate
// and start unloading classes.
// See https://github.com/netty/netty/issues/6596.
FastThreadLocal.removeAll();
STATE_UPDATER.set(SingleThreadEventExecutor.this, ST_TERMINATED);
threadLock.countDown();
if (logger.isWarnEnabled() && !taskQueue.isEmpty()) {
logger.warn("An event executor terminated with " +
"non-empty task queue (" + taskQueue.size() + ')');
}
terminationFuture.setSuccess(null);
}
}
}
}
});
}
}
ThreadPerTaskExecutor.execute
public final class ThreadPerTaskExecutor implements Executor {
//我们要执行开启一个线程时,只需要调用此方法传一个Runnable任务 此方法就会通过threadFactory创建一个线程去执行
@Override
public void execute(Runnable command) {
//new DefaultThreadFactory()
threadFactory.newThread(command).start();
}
}
2.2 AbstractUnsafe#register0
AbstractUnsafe#register0 register0()添加到在SingleThreadEventExecutor#execute添加到任务队列,在SingleThreadEventExecutor#doStartThread中,NioEventLoop绑定新创建的线程后,由NioEventLoop绑定的线程从任务队列中获取任务去执行。
protected abstract class AbstractUnsafe implements Unsafe {
private void register0(ChannelPromise promise) {
try {
// 检查通道是否仍然打开,因为它可以在寄存器的平均时间内关闭
// 调用在eventLoop之外
//promise=DefaultChannelPromise
if (!promise.setUncancellable() || !ensureOpen(promise)) {
return;
}
boolean firstRegistration = neverRegistered;
//调用NioServerSocketChannel 通过反射创建出来nio底层channel的register方法 选择器看不同操作系统
//AbstractNioChannel.doRegister
doRegister();
neverRegistered = false;
registered = true;
// 确保在实际通知承诺之前调用handlerAdded(…)。这是需要的
// 用户可能已经通过ChannelFutureListener中的管道触发事件。
/**
* 回调ServerBootstrap.init中添加到pipeline中的ChannelInitializer匿名内部类的initChannel
* 里面会将ServerBootstrapAcceptor添加到NioServerSocketChannel的pipeline中
*/
//会执行handlerAdded方法
//回调ChannelInitializer.handlerAdded
//2.3 DefaultChannelPipeline#invokeHandlerAddedIfNeeded
pipeline.invokeHandlerAddedIfNeeded();
safeSetSuccess(promise);
//会执行channelRegistered
pipeline.fireChannelRegistered();
/**
* 只有当通道从未被注册时,才激活该通道。这可以防止解雇
* 如果取消注册并重新注册通道,则多个通道将激活。
*
* NioServerSocketChannel#isActive()返回false
* NioSocketChannel#isActive()返回true
*
* NioServerSocketChannel在调用doBind0()之后才会调用 pipeline.fireChannelActive();修改感兴趣的事件
*
*/
if (isActive()) { //NioServerSocketChannel#isActive()返回false NioSocketChannel#isActive()返回true
if (firstRegistration) {
/**
* 修改感兴趣的事件为OP_READ
*/
pipeline.fireChannelActive();
} else if (config().isAutoRead()) {
// 这个通道之前已经注册,并设置了autoRead()。这意味着我们需要开始读取
// 这样我们就可以处理入站数据。
//
// See https://github.com/netty/netty/issues/4805
beginRead();
}
}
} catch (Throwable t) {
// 直接关闭通道,避免FD泄漏。
closeForcibly();
closeFuture.setClosed();
safeSetFailure(promise, t);
}
}
}
AbstractNioChannel#doRegister
public abstract class AbstractNioChannel extends AbstractChannel {
//注册核心方法
protected void doRegister() throws Exception {
boolean selected = false;
for (;;) {
try {
//javaChannel() ==> ServerSocketChannel 通过反射创建出来nio底层channel
//调用Nio底层将ServerSocketChannel注册到selector上
//注意:感兴趣的事件是0 read:1 write:4 connect:8 accept:16 即目前不对任何事件感兴趣
//将this即NioServerSocketChannel作为attr传入 在有连接进来时可以通过其包装的Java nio的ServerSocketChannel接受连接
selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this);
return;
} catch (CancelledKeyException e) {
if (!selected) {
//强制选择器现在选择,因为“已取消”的SelectionKey可能仍然是
//缓存并没有删除,因为还没有调用Select.select(..)操作。
eventLoop().selectNow();
selected = true;
} else {
//我们之前在选择器上强制执行了select操作,但是SelectionKey仍然缓存
//不管什么原因。JDK错误?
throw e;
}
}
}
}
}
2.3 DefaultChannelPipeline#invokeHandlerAddedIfNeeded
DefaultChannelPipeline#invokeHandlerAddedIfNeeded
public class DefaultChannelPipeline implements ChannelPipeline {
final void invokeHandlerAddedIfNeeded() {
assert channel.eventLoop().inEventLoop();
/**
* 只会进去一次
*/
if (firstRegistration) {
firstRegistration = false;
//回调
callHandlerAddedForAllHandlers();
}
}
private void callHandlerAddedForAllHandlers() {
final PendingHandlerCallback pendingHandlerCallbackHead;
synchronized (this) {
assert !registered;
// 该通道本身已注册。
registered = true;
pendingHandlerCallbackHead = this.pendingHandlerCallbackHead;
this.pendingHandlerCallbackHead = null;
}
//这必须发生在synchronized(…)块之外,否则handlerAdded(…)可能在while中被调用
//如果handleradd(…)试图从外部添加另一个处理程序,则会持有锁,从而产生死锁
// EventLoop。
//维护着一个链表 链表在哪添加元素的 => 调用pipeline.addLast()
PendingHandlerCallback task = pendingHandlerCallbackHead;
while (task != null) {
//PendingHandlerAddedTask 回调ChannelInitializer.handlerAdded -> 调用ChannelInitializer.initChannel
/**
* 循环执行NioServerSocketChannle.pipeline中的用来初始化netty server的 ChannelHandler
* netty中把用于初始化的ChannelHandler叫做ChannelInitializer ChannelInitializer是ChannelHandler的子类
* 主要是为了执行ServerBootstrap.init中添加到pipeline中的ChannelInitializer匿名内部类的initChannel()方法
* 将ServerBootstrapAcceptor添加到pipeline中
* 执行完成后将用来初始化的ChannelHandler从pipeline移除
*/
//PendingHandlerAddedTask.execute
task.execute();
//找下一个用来初始化netty server的 ChannelInitializer
//在调用pipeline.addLast()时会维护这个链表
task = task.next;
}
}
}
PendingHandlerAddedTask#execute
private final class PendingHandlerAddedTask extends PendingHandlerCallback {
PendingHandlerAddedTask(AbstractChannelHandlerContext ctx) {
super(ctx);
}
@Override
public void run() {
callHandlerAdded0(ctx);
}
@Override
void execute() {
//ctx.executor(); 当ctx中的executor为空的时候 获取NioEventLoop
EventExecutor executor = ctx.executor();
if (executor.inEventLoop()) {
//回调DefaultChannelPipeline.handlerAdded方法
callHandlerAdded0(ctx);
} else {
try {
executor.execute(this);
} catch (RejectedExecutionException e) {
if (logger.isWarnEnabled()) {
logger.warn(
"Can't invoke handlerAdded() as the EventExecutor {} rejected it, removing handler {}.",
executor, ctx.name(), e);
}
remove0(ctx);
ctx.setRemoved();
}
}
}
}
public class DefaultChannelPipeline implements ChannelPipeline {
private void callHandlerAdded0(final AbstractChannelHandlerContext ctx) {
try {
//回调handlerAdded方法
//AbstractChannelHandlerContext#callHandlerAdded
ctx.callHandlerAdded();
} catch (Throwable t) {
boolean removed = false;
try {
remove0(ctx);
ctx.callHandlerRemoved();
removed = true;
} catch (Throwable t2) {
if (logger.isWarnEnabled()) {
logger.warn("Failed to remove a handler: " + ctx.name(), t2);
}
}
if (removed) {
fireExceptionCaught(new ChannelPipelineException(
ctx.handler().getClass().getName() +
".handlerAdded() has thrown an exception; removed.", t));
} else {
fireExceptionCaught(new ChannelPipelineException(
ctx.handler().getClass().getName() +
".handlerAdded() has thrown an exception; also failed to remove.", t));
}
}
}
}
AbstractChannelHandlerContext#callHandlerAdded
abstract class AbstractChannelHandlerContext implements ChannelHandlerContext, ResourceLeakHint {
final void callHandlerAdded() throws Exception {
// We must call setAddComplete before calling handlerAdded. Otherwise if the handlerAdded method generates
// any pipeline events ctx.handler() will miss them because the state will not allow it.
//判断handlerState等于1 并且设置handlerState为2
if (setAddComplete()) {
//ChannelInitializer.handlerAdded
handler().handlerAdded(this);
}
}
}
ChannelInitializer#handlerAdded
public abstract class ChannelInitializer<C extends Channel> extends ChannelInboundHandlerAdapter {
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
//在AbstractUnsafe.register0中将registered改为true
if (ctx.channel().isRegistered()) {
//会调用ChannelInitializer.initChannel
if (initChannel(ctx)) {
// We are done with init the Channel, removing the initializer now.
removeState(ctx);
}
}
}
private boolean initChannel(ChannelHandlerContext ctx) throws Exception {
if (initMap.add(ctx)) { // Guard against re-entrance.
try {
initChannel((C) ctx.channel());
} catch (Throwable cause) {
// Explicitly call exceptionCaught(...) as we removed the handler before calling initChannel(...).
// We do so to prevent multiple calls to initChannel(...).
exceptionCaught(ctx, cause);
} finally {
//删除此节点 ChannelInitializer匿名内部类
ChannelPipeline pipeline = ctx.pipeline();
if (pipeline.context(this) != null) {
pipeline.remove(this);
}
}
return true;
}
return false;
}
}