Netty服务端初始化过程源码分析

server端启动

public class MyServer {
    public static void main(String[] args) throws Exception{
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try{
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new MyServerInitializer());
            ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();
            channelFuture.channel().closeFuture().sync();
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

new NioEventLoopGroup()如果没有指定线程数,就是cpu核心数超线程*2。

serverBootstrap.group(bossGroup,workerGroup)代码分析:

public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
        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;
    }

childGroup会保存在ServerBootstrap的成员变量this.childGroup上,parentGroup调用super.group(parentGroup)保存在ServerBootstrap父类AbstractBootstrap的成员变量this.group上。

serverBootstrap.channel(NioServerSocketChannel.class)源码分析:
Netty服务端初始化过程源码分析_第1张图片
Netty服务端初始化过程源码分析_第2张图片
可以看到NioServerSocketChannel.class保存在ReflectiveChannelFactory的成员变量this.clazz上。
Netty服务端初始化过程源码分析_第3张图片
将new出来的ReflectiveChannelFactory实例保存在AbstractBootstrap的成员变量this.channelFactory上。

serverBootstrap.childHandler(new MyServerInitializer())源码分析:
Netty服务端初始化过程源码分析_第4张图片
new MyServerInitializer()保存在ServerBootstrap的成员变量this.childHandler上。

serverBootstrap.bind(8899)源码分析:
Netty服务端初始化过程源码分析_第5张图片
Netty服务端初始化过程源码分析_第6张图片
Netty服务端初始化过程源码分析_第7张图片
进入initAndRegister()方法:
Netty服务端初始化过程源码分析_第8张图片
这边的channelFactory就是之前保存的ReflectiveChannelFactory实例,进入ReflectiveChannelFactory的newChannel():
Netty服务端初始化过程源码分析_第9张图片
这里的clazz就是之前传进来的NioServerSocketChannel.class,
进入NioServerSocketChannel.class的无参构造函数:
Netty服务端初始化过程源码分析_第10张图片
进入newSocket(SelectorProvider provider)方法,该方法返回一个ServerSocketChannel,SelectorProvider已经是java.nio下的了:
Netty服务端初始化过程源码分析_第11张图片
再返回this(newSocket(DEFAULT_SELECTOR_PROVIDER)):
Netty服务端初始化过程源码分析_第12张图片
这边定义了ServerSocketChannel感兴趣事件是SelectionKey.OP_ACCEPT;
进入super(null, channel, SelectionKey.OP_ACCEPT):
Netty服务端初始化过程源码分析_第13张图片
Netty服务端初始化过程源码分析_第14张图片
在这里完成channel的赋值this.ch=ch,并通过ch.configureBlocking(false)设置ServerSocketChannel为非阻塞。进入父类构造super(parent):
Netty服务端初始化过程源码分析_第15张图片
完成了pipeline的创建。一个pipeline只会与一个channel绑定。
完成了channel的创建之后,再进入initAndRegister()的init(channel)方法:
Netty服务端初始化过程源码分析_第16张图片
前面为ServerSocketChannel的配置赋值,ChannelOption主要维护TCP/IP参数的设定,而AttributeKey主要维护业务数据,用户可以在前面设置的key-value,在后面的某个handler可以取出该业务数据。并在ServerSocketChannel对应的pipeline中添加一个ServerBootstrapAcceptor实例,可参见Reactor中Acceptor组件角色。

执行完initAndRegister()方法后,往下继续执行
Netty服务端初始化过程源码分析_第17张图片
进入doBind0(regFuture, channel, localAddress, promise)方法:
Netty服务端初始化过程源码分析_第18张图片
channel.eventLoop()的目的是要在channel注册上的eventLoop所关联的线程去执行Runnable,所以channel上的I/O操作都是单线程,线程安全的。

进入 channel.bind(localAddress,promise)
.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
在这里插入图片描述
通过关联的pipeline完成bind操作:
在这里插入图片描述
Netty服务端初始化过程源码分析_第19张图片
Netty服务端初始化过程源码分析_第20张图片
Netty服务端初始化过程源码分析_第21张图片
再往下就进入unsafe去完成bind操作。

你可能感兴趣的:(netty)