Netty Nio服务器

本文详细介绍了Netty Nio服务器的启动流程,包括构建ServerBootStrap对象,设置服务端连接参数,配置EventLoopGroup,设置childHandler,channelFactory,以及bind服务地址的过程。特别强调了NioEventLoop在处理请求中的角色,以及ServerSocketChannel和NioSocketChannel在连接管理和I/O操作中的作用。同时,文章提及了内核的SYN和ACCEPT队列,以及NioEventLoop不断调用Selector选择有I/O操作的channel进行处理。
摘要由CSDN通过智能技术生成

netty服务端处理流程

构建ServerBootStrap对象;

1、设置服务端连接参数;
2、设置EventLoopGroup对象,用以处理服务段请求;

NioEventLoopGroup可以设置多个线程,每个线程对应一个NioEventLoop对象用以处理请求;NioEventLoop实例分两类,一类bind服务地址,accept远程请求连接event,称为boss组,一类处理请求的数据并返回响应数据event,称为worker组;可以只创建一个group,两类NioEventLoop实例公用,也可以分别创建boos和worker组,分别处理两类事件,避免数据处理太耗时NioEventLoop实例被占用而无发接收请求。此外为主监听channel和子处理channel设置参数。
bossGroup负责接收连接,为每一个连接创建从线程,不仅接收也处理;
workGroup负责连接的i/o操作,为每个请求创建处理线程;

4、设置childHandler对象值(channel初始化handler);

初始化请求数据处理的channel ChannelPipeline里的handler list;请求数据处理被分隔成一个个part,每个part由对应的handler处理,形成数据处理的strem流。

5、channelFactory设置

本例为NioServerSocketChannel,用来创建channel

6、ServerBootStrap bind服务地址
6.1创建ServerSocketChannel

根据channelFactory设置的channel类,创建对应的类NioServerSocketChannel实例;
NioServerSocketChannel实例会创建一个ServerSocketChannelImpl实例来初始化SelectableChannel ch变量;

    private static ServerSocketChannel newSocket(SelectorProvider provider) {
        try {
            /**
             *  Use the {@link SelectorProvider} to open {@link SocketChannel} and so remove condition in
             *  {@link SelectorProvider#provider()} which is called by each ServerSocketChannel.open() otherwise.
             *
             *  See <a href="https://github.com/netty/netty/issues/2308">#2308</a>.
             */
            return provider.openServerSocketChannel();
        } catch (IOException e) {
            throw new ChannelException(
                    "Failed to open a server socket.", e);
        }
    }

    private final ServerSocketChannelConfig config;

    /**
     * Create a new instance
     */
    public NioServerSocketChannel() {
        this(newSocket(DEFAULT_SELECTOR_PROVIDER));
    }
6.2地址绑定

将ServerSocketChannel中的监听句柄fd绑定到服务地址上;
ServerBootStrap调用bind()方法,在bind()方法中会创建NioServerSocketChannel对象,并将NioServerSocketChannel对象中的ServerSocketChannel对象(SelectableChannel ch变量,监听sockets)注册给boos group里的某个EventLoop对象里的Selector变量,并形成一个SelectionKey对象;
在ServerSocketChannel bind()方法中,将监听句柄fd 通过bind系统调用绑定到服务地址,然后通过listen系统调用让内核监听此句柄。
(注:这里bind过程中,一个监听channel只占boos group一个EventLoop线程,一般情况下boss group里一个线程就够了(main reactor通常只用到boos group线程组中的一个主要是因为Server只能绑定一个SocketAddress,并且只能绑定一次);如果bind多个地址,boss group可以设置多个线程,增加并发,bind多个地址可能需要代理服务器对外提供统一服务地址;还有一种说法是boos多线程做Auth/login/shake-hand/SLA用,没有时间过)。
在bind的过程中ServerSocketchannel会将SO_BACKLOG参数传给内核,用来限制内核连接ACCEPT队列的大小,当ACCEPT队列满了之后,内核网络服务会把SYN请求丢掉。内核网络会维持两个队列SYN和ACCEPT,当服务端接收到SYN请求后,会返回SYNACK,并将请求放入SYN队列,当3次握手完成后,将连接请求放入ACCEPT队列,然后通过accept()系统调用取出,供用户使用。

接下来,NioEventLoop task会不断地调用Slector 的select()方法,获取有i/o操作的channel。比如,NioServerSocketChannel对应的read事件,AbstractNioMessageChannel.NioMessageUnsafe.read()方法调用NioServerSocketChannel的doReadMessages()方法accept socket,并把对应的socketchannel给NioSocketChannel实例,由NioSocketChannel实例处理对应的请求。

请求服务

向netty服务器发送一个http请求,监听、创建注册对应的socket channel、io读写操作,这里最好debug调试。
在调试中可以看到NioServerSocketChannel有一个ServerSocketChannel对象,负责绑定服务地址,监听服务,NioSocketChannel有一个SocketChannel,负责请求i/o操作。
在这里插入图片描述
在这里插入图片描述

netty 类分析

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值