Netty源码分析-服务端启动流程

接上一节eventLoopGroup初始化过程,本节分析服务端启动的流程。

//配置服务端的NIO线程组
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workGroup = new NioEventLoopGroup();
try {
    ServerBootstrap bootstrap = new ServerBootstrap();
    bootstrap.group(bossGroup, workGroup)
            .channel(NioServerSocketChannel.class)
            .childHandler(new ChannelInitializer() {
                @Override
                protected void initChannel(SocketChannel channel) throws Exception {
                    channel.pipeline()
                            .addLast(new GateServerHandler());
                }
            })
            .option(ChannelOption.SO_BACKLOG, 512)
            .option(ChannelOption.SO_KEEPALIVE, true);
    //绑定端口,同步等待成功
    ChannelFuture f = bootstrap.bind(port).sync();
    f.channel().closeFuture().sync();
}catch (Exception e){
    e.printStackTrace();
}finally {
    try {
        bossGroup.shutdownGracefully().sync();
        workGroup.shutdownGracefully().sync();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

1. bootstrap.group(bossGroup, workGroup)

public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
    super.group(parentGroup);
    if (childGroup == null) {
        throw new NullPointerException("childGroup");
    } else if (this.childGroup != null) {
        throw new IllegalStateException("childGroup set already");
    } else {
        this.childGroup = childGroup;
        return this;
    }
}

bossGroup赋值给父类AbstractBootstrap的group, workGroup赋值给ServerBootstrap的childGroup。

2. bootstrap.channel(NioServerSocketChannel.class)

public B channel(Classextends C> channelClass) {
    if (channelClass == null) {
        throw new NullPointerException("channelClass");
    } else {
        return this.channelFactory((io.netty.channel.ChannelFactory)(new ReflectiveChannelFactory(channelClass)));
    }
}

ReflectiveChannelFactory封装了传入的NioServerSocketChannel.class,再赋值给AbstractBootstrap.channelFactory

3. bootstrap.childHandler(**)

public ServerBootstrap childHandler(ChannelHandler childHandler) {
    if (childHandler == null) {
        throw new NullPointerException("childHandler");
    } else {
        this.childHandler = childHandler;
        return this;
    }
}
自定义childHandler,赋值给ServerBootstrap.childHandler

4. bootstrap.option

SO_KEEPALIVE:保持长链接

SO_BACKLOG:TCP三次握手ack队列的大小。更具体的内容可以参考tcp backlog参数

5. bootstrap.bind

public ChannelFuture bind(SocketAddress localAddress) {
    this.validate();
    if (localAddress == null) {
        throw new NullPointerException("localAddress");
    } else {
        return this.doBind(localAddress);
    }
}

校验AbstractBootstrap的group和channelFactory是否为null,校验ServerBootstrap的childGroup和childHandler是否为null。重点分析下AbstractBootstrap.doBind过程

private ChannelFuture doBind(final SocketAddress localAddress) {
    final ChannelFuture regFuture = this.initAndRegister();
    final Channel channel = regFuture.channel();
    if (regFuture.cause() != null) {
        return regFuture;
    } else if (regFuture.isDone()) {
        ChannelPromise promise = channel.newPromise();
        doBind0(regFuture, channel, localAddress, promise);
        return promise;
    } else {
        final AbstractBootstrap.PendingRegistrationPromise promise = new AbstractBootstrap.PendingRegistrationPromise(channel);
        regFuture.addListener(new ChannelFutureListener() {
            public void operationComplete(ChannelFuture future) throws Exception {
                Throwable cause = future.cause();
                if (cause != null) {
                    promise.setFailure(cause);
                } else {
                    promise.registered();
                    AbstractBootstrap.doBind0(regFuture, channel, localAddress, promise);
                }

            }
        });
        return promise;
    }
}

5.1 initAndRegister初始化注册过程

final ChannelFuture initAndRegister() {
    Channel channel = null;

    try {
        channel = this.channelFactory.newChannel();
        this.init(channel);
    } catch (Throwable var3) {
        if (channel != null) {
            channel.unsafe().closeForcibly();
            return (new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE)).setFailure(var3);
        }

        return (new DefaultChannelPromise(new FailedChannel(), GlobalEventExecutor.INSTANCE)).setFailure(var3);
    }

    ChannelFuture regFuture = this.config().group().register(channel);
    if (regFuture.cause() != null) {
        if (channel.isRegistered()) {
            channel.close();
        } else {
            channel.unsafe().closeForcibly();
        }
    }

    return regFuture;
}
this.newChannel方法在ReflectiveChannelFactory类中通过反射实例化NioServerSocketChannel。

NioServerSocketChannel实例化过程

public NioServerSocketChannel(java.nio.channels.ServerSocketChannel channel) {
    super((Channel)null, channel, 16);
    this.config = new NioServerSocketChannel.NioServerSocketChannelConfig(this, this.javaChannel().socket());
}
  • 创建AbstractNioMessageChannel.NioMessageUnsafe
  • 创建DefaultChannelPipeline,内部维护了一个AbstractChannelHandlerContext(head,tail)链表
  • 设置NioServerSocketChannel的SelectionKey为OP_ACCEPT
  • 设置NioServerSocketChannel为非阻塞模式
  • 创建ServerSocket

this.init()

主要工作是把ServerBootstrapAcceptor放到了pipeline的链表中

p.addLast(new ChannelHandler[]{new ChannelInitializer() {
    public void initChannel(final Channel ch) throws Exception {
        final ChannelPipeline pipeline = ch.pipeline();
        ChannelHandler handler = ServerBootstrap.this.config.handler();
        if (handler != null) {
            pipeline.addLast(new ChannelHandler[]{handler});
        }

        ch.eventLoop().execute(new Runnable() {
            public void run() {
                pipeline.addLast(new ChannelHandler[]{new ServerBootstrap.ServerBootstrapAcceptor(ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs)});
            }
        });
    }
}});

this.config().group().register(channel)

group方法返回的是bossGroup,bossGroup是MultithreadEventLoopGroup的子类

public ChannelFuture register(Channel channel) {
    return this.next().register(channel);
}

跟进this.next方法,可以看到该方法是从chooser中拿出一个eventExecutor

public EventExecutor next() {
    return this.chooser.next();
}

register调用了SingleThreadEventLoop类的方法,首先将NioServerSocketChannel和当前线程封装成DefaultChannelPromise对象

public ChannelFuture register(Channel channel) {
    return this.register((ChannelPromise)(new DefaultChannelPromise(channel, this)));
}

再调用unsafe的register方法,由前面可知,unsafe就是AbstractNioMessageChannel.NioMessageUnsafe对象

public ChannelFuture register(ChannelPromise promise) {
    ObjectUtil.checkNotNull(promise, "promise");
    promise.channel().unsafe().register(this, promise);
    return promise;
}
  • AbstractChannel.this.doRegister()将NioServerSocketChannel注册到当前线程绑定的selector上
  • AbstractChannel.this.pipeline.invokeHandlerAddedIfNeeded()如果自定义了handler(注意不是childHandler),将handler加到pipeline的链表中
  • AbstractChannel.this.pipeline.fireChannelRegistered(),在head->tail的调用链上传递注册事件
boolean firstRegistration = this.neverRegistered;
AbstractChannel.this.doRegister();
this.neverRegistered = false;
AbstractChannel.this.registered = true;
AbstractChannel.this.pipeline.invokeHandlerAddedIfNeeded();
this.safeSetSuccess(promise);
AbstractChannel.this.pipeline.fireChannelRegistered();
if (AbstractChannel.this.isActive()) {
    if (firstRegistration) {
        AbstractChannel.this.pipeline.fireChannelActive();
    } else if (AbstractChannel.this.config().isAutoRead()) {
        this.beginRead();
    }
}

5.2 AbstractBootstrap.doBind

再回到AbstractBootstrap.doBind方法上,跟进doBind0 -> AbstractChannel.bind -> DefaultChannelPipeline.bind 

public final ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) {
    return this.tail.bind(localAddress, promise);
}

this.findContextOutbound方法从tail开始循环向前找到属性outbound为true的AbstractChannelHandlerContext,返回HeadContext,调用headContext的bind方法

final AbstractChannelHandlerContext next = this.findContextOutbound();
EventExecutor executor = next.executor();
if (executor.inEventLoop()) {
    next.invokeBind(localAddress, promise);
}

跟进unsafe.bind方法

try {
    AbstractChannel.this.doBind(localAddress);
} catch (Throwable var5) {
    this.safeSetFailure(promise, var5);
    this.closeIfClosed();
    return;
}

if (!wasActive && AbstractChannel.this.isActive()) {
    this.invokeLater(new Runnable() {
        public void run() {
            AbstractChannel.this.pipeline.fireChannelActive();
        }
    });
}

AbstractChannel.this.doBind(localAddress)调用java nio的ServerSocketChannelImpl绑定了地址和端口

protected void doBind(SocketAddress localAddress) throws Exception {
    if (PlatformDependent.javaVersion() >= 7) {
        this.javaChannel().bind(localAddress, this.config.getBacklog());
    } else {
        this.javaChannel().socket().bind(localAddress, this.config.getBacklog());
    }

}

AbstractChannel.this.pipeline.fireChannelActive在pipeline链表上传播Active和Read事件

public void channelActive(ChannelHandlerContext ctx) throws Exception {
    ctx.fireChannelActive();
    this.readIfIsAutoRead();
}

服务端完成绑定,并且激活channel和等待客户端read事件

你可能感兴趣的:(Netty)