美文网首页
Netty源码

Netty源码

作者: upup果 | 来源:发表于2021-03-16 22:45 被阅读0次

服务端启动过程

EventLoopGroup workerGroup = new NioEventLoopGroup()的执行

1)NioEventLoopGroup 的无参数构造函数会调用 NioEventLoopGroup 的有参数构造函数,最终把参数nThreads=16,executor=null
,chooserFactory=DefaultEventExecutorChooserFactory.INSTANCE
,selectorProvider=SelectorProvider.provider()
,selectStrategyFactory=DefaultSelectStrategyFactory.INSTANCE
,rejectedExecutionHandler=RejectedExecutionHandlers.reject()
传递给父类 MultithreadEventLoopGroup 的有参数构造函数。
2)父类 MultithreadEventLoopGroup 的有参数构造函数创建一个 NioEventLoop 的容器 children = new EventExecutor[nThreads],并构建出 16 个 NioEventLoop 的实例放入其中。
3)构建每一个 NioEventLoop 调用的是 children[i] = newChild(executor, args)。
4)newChild()方法最终调用了 NioEventLoop 的构造函数,初始化其中的选择器、任务队列、执行器等成分。

ServerBootstrap 实例的创建与配置

1).group(bossGroup, workerGroup)把 bossGroup 和 workerGroup 两个参数赋值给 ServerBootstrap 的成员变量 group(从父类 AbstractBootstrap 继承而来)和 childGroup。
2).channel(NioServerSocketChannel.class)通过反射机制给当前 ServerBootstrap 中的 channelFactory 属性(从父类 AbstractBootstrap 继承而来)赋值。在调用.bind()的时候 channelFactory 会创建 NioServerSocketChannel 的实例。
3).option(ChannelOption.SO_BACKLOG, 100)将可选项放入一个 ChannelOption 集合。
4).handler(new LoggingHandler(LogLevel.INFO))将 Netty 提供的一个日志记录 Handler 赋值给 ServerBootstrap 实例的 handler 属性(从父类 AbstractBootstrap 继承而来)。这个 Handler 最终在 ServerBootstrap.init()方法中被放入 NioServerSocketChannel 实例的 pipeline 中。
5).childHandler(...)的作用是为接收客户端连接请求产生的 NioSocketChannel 实例的 pipeline 添加两个 Handler,分别是做 SSL 加密处理的 Handler,以及一个我们自定义的 Handler。

执行 ServerBootstrap.bind(PORT)时发了什么

1)首先调用 AbstractBootstrap 中的 doBind()方法完成 NioServerSocketChannel 实例的初始化和注册。
2)然后调用 NioServerSocketChannel 实例的 bind()方法。
3)NioServerSocketChannel 实例的 bind()方法最终调用 sun.nio.ch.Net 中的 bind()和 listen()完成端口绑定和客户端连接监听。
4)sun.nio.ch.Net 中的 bind()和 listen()底层都是 JVM 进行的系统调用。
5)bind 完成后会进入 NioEventLoop 中的死循环,不断执行以下三个过程
select:轮训注册在其中的 Selector 上的 Channel 的 IO 事件
processSelectedKeys:在对应的 Channel 上处理 IO 事件
runAllTasks:再去以此循环处理任务队列中的其他任务

Netty 服务端接收客户端连接请求

1)服务器端 bossGroup 中的 EventLoop 轮训 Accept 事件、获取事件后在 processSelectedKey()方法中调用 unsafe.read()方法,这个 unsafe 是内部类 io.netty.channel.nio.AbstractNioChannel.NioUnsafe 的实例,unsafe.read()方法由两个核心步骤组成:doReadMessages()和 pipeline.fireChannelRead()。
2)doReadMessages()用于创建 NioSocketChannel 对象,包装了 JDK 的 SocketChannel 对象,并且添加了 pipeline、unsafe、config 等成分。
3)pipeline.fireChannelRead()用于触发服务端 NioServerSocketChannel 的所有入站 Handler 的 channelRead()方法,在其中的一个类型为 ServerBootstrapAcceptor 的入站 Handler 的 channelRead()方法中将新创建的 NioSocketChannel 对象注册到 workerGroup 中的一个 EventLoop 上,该 EventLoop 开始监听 NioSocketChannel 中的读事件。

相关文章

网友评论

      本文标题:Netty源码

      本文链接:https://www.haomeiwen.com/subject/poujcltx.html