栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Netty源码分析(一) --- Server/Client启动流程,建立连接和Read剖析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Netty源码分析(一) --- Server/Client启动流程,建立连接和Read剖析

一、Netty源码分析

https://github.com/netty/netty/tree/4.1/example/src/main/java/io/netty/example/echo

上找到echo这个example

1.1 服务端启动流程 1.1.1 两个NioEventLoopGroup

服务端代码首先要定义两个NioEventLoopGroup,打个断点进去

NioEventLoopGroup继承MultithreadEventLoopGroup,加载的时候执行父类静态方法,初始化DEFAULT_EVENT_LOOP_THREADS = cpu核数 * 2

如果是无参构造就让默认children线程为12个,而bossgroup是有参,只有1个线程,workergroup就是12个线程。这些线程就是事件循环组

这个过程中还会生成一个Selector多路复用器的Provider,供之后生成Selector使用,是由操作系统决定的,Windows下就是WindowsSelectorProvider

这个位置就是生成children线程的地方,生成完之后为每个线程加上结束回调监听器

1.1.2 ServerBootStrap

接下来在ServerBootStrap那打个断点

进去看看,加载ServerBootstrap会先加载AbstractBootstrap,声明了一堆变量,实际上都没初始化,留给后面链式编程添加属性

然后针对链式编程进行断点研究

group(bossGroup,workerGroup):将bossgroup赋给group,workergroup赋给childgroup

channel(NioServerSocketChannel.class):用反射创建一个ChannelFactory,为之后创建NioServerSockerChannel提供一个工厂

option(ChannelOption.SO_BACKLOG, 100):添加一些TCP参数,可以看到是放进options这个linkedHashMap中,供之后使用

handler(new LoggingHandler(LogLevel.INFO)):设置handler这个属性为LoggingHandler,即bossgroup的handler为LoggingHandler

childHandler(new ChannelInitializer(){...}):设置childHandler,即workergroup的handler

总结: ServerBootstrap实际上就是一个辅助启动类或者说是个配置类,将一些初始化属性添加进ServerBootstrap,供之后使用

1.1.3 ChannelFuture f = b.bind(PORT)

实际上bind方法才是真正工作的地方

实际上会走doBind()方法,doBind方法里有两个核心方法:initAndRegister(),doBind0()

initAndRegister()方法就是先构建一个NioServerSocketChannel,然后用init()方法初始化channel,初始化完后register这个channel

先看init(),在init这个位置才将开始ServerBootstrap添加的options和attributes添加到ServerSocketChannel上,

然后拿到pipeline,往pipeline添加之前的handler这里是LoggingHandler,ServerBootstrapAcceptor监听ACCEPT连接事件

再来看register(channel):首先用next()从executors(线程池组)中获取一个executor(线程池)来执行register方法

查看在不在当前的事件循环组,是就直接在当前register0(),不是就让这个eventLoop自己执行

继续看register0(),发现还有一个doRegister(),之后safeSetSuccess()就代表注册完成了,后面的pipeline.fireChannelRegistered()是把遍历我们加入到channelpipeline的handler查看这些handler有没有对ChannelRegistered事件有操作

死循环获取selectionKey,javaChannel实际上是Nio的channelServerSocketChannel,然后就进入NIO的register()了,用NIO的一套进行注册了

之后safeSetSuccess()就代表注册完成了,safeSetSuccess()追进去就是notifyListeners,通知监听器我准备好了

继续执行,回到doBind()方法,接下来执行doBind0()

之后回到bind()方法执行fireChannelActive(),通知pipeline链上的handler:Channel开始活动,查看是否有Handler有ChannelActive的方法

channelActive不仅会让handler调用他们处理ChannelActive的方法,还会让channel开始读数据

readIfIsAutoRead()调用到最后到beginRead()

之后执行到beginRead()->doBeginRead()

之前初始化的时候设置ops为0,现在设置为16,表示Selectior开始监听ACCEPT事件

最后进入NioEventLoop的run方法,开始Select

1.2 客户端启动流程 1.2.1 connect

Bootstrap和服务端类似,直接看connect方法

doResolveAndConnect():核心initAndRegister()和doResolveAndConnect0()

先看initAndRegister():和ServerBootStrap一样都是调用父类AbstractBootstrap的initAndRegister

init是交给子类来重写的,可以看到ServerBootstrap的init要做的事就比较少了

init完成之后调用AbstractChannel的register()-->register0() ,和ServerBootstrap类似,设置成功回调,通知pipeline进行ChannelRegistered操作

随后从doResolveAndConnect0执行到doConnect,使用channel.connect()连接Socket地址

追进去,从pipeline获取ChannelHandlerContext,找到出站的HandlerContext,调用这些HandlerContext的invokeConnect方法

链的最后调用unsafe.connect()

进入doConnect:NIO方式连接远程地址

然后就可以看到Server的控制台:连接成功了

之后就是select了,select到了就processSelectedKeys

1.3 Server和Client建立连接和Read的过程 1.3.1 Server端

开启一个Client,这个地方的select会调用两次,第一次是建立ACCEPT连接事件,第二次是READ读事件

调用selector.select(),监控是否有事件发送

select到了一个,selectCnt++,调用processSelectedKeys()

判空,然后调用processSelectedKeysOptimized()

processSelectedKeysOptimized()方法调用processSelectedKey

根据SelectionKey是什么事件调用相关方法,此处是read和accept,都调用read

pipeline.fireChannelRead(byteBuf)通知pipeline做ChannelRead操作,也就是这个时候进行的输出

pipeline.fireChannelReadComplete()通知pipeline做ChannelReadComplete工作

可以看到输出结果,从ACCEPT到READ两次ChannelRead和两次READ COMPLETE,就是因为ACCEPT和READ都是走的read()方法

1.3.2 Client端

Client同样select,但是走CONNECT这个地方

连接事件:

走到最后就是pipeline.fireChannelActive

调用pipeline链,到自定义的Handler有channlActive事件,这时候发消息过期,就是Server端处理ChannelRead的过程了

11.4 服务端客户端启动总结

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/785664.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号