一: netty服务器启动过程
serverBootstrap.bind(hostname, port)--->
doBind(localAddress);-->
1.1: initAndRegister();初始化并注册-->
1.1.1: channelFactory.newChannel();-->ReflectiveChannelFactory.newChannel()--->可以看到这里是使用反射创建的 channel对象,这里的channel对象是JDK的channel,然后netty包装了JDK的channel
1.1.2: init(channel); 初始化channel,核心是和channelPipeline相关,--->ServerBootstrap.init()-->这个方法可以看出是给channel的 各个map设置值.给 channel的 pipeline添加处理器, channel添加pipeline
1.1.2.1: pipeline.addLast(handler) 这个是初始化的核心,设置pipeline --->DefaultChannelPipeline.addList()-->checkMultiplicity(handler);这里看到先检查双向链表的容量--------
newCtx = newContext(group, filterName(name, handler), handler);这个是创建了一个新的上下文 AbstractChannelHandlerContext对象,这个对象负责ChannelHandler
和 ChannelPipeline 之间关联, 之后将这个context添加到双向链表最后, 最后,异步/同步调用callHandlerAdded0(newCtx); 1.1.3: ChannelFuture regFuture = config().group().register(channel); ----> 这是将 初始化完成的 NioServerSocketChannel 注册到对应的事件循环组中,(bossgroup, workgroup),并返回这个异步执行占位符 future 1.2: doBind0(regFuture, channel, localAddress, promise);--->channel.bind(localAddress, promise)--->DefaultChannelPipeline.bind() -->tail.bind(localAddress, promise);--->next.invokeBind(localAddress, promise);
--->((ChannelOutboundHandler) handler()).bind(this, localAddress, promise);--->DefaultChannelPipeline.bind()-->unsafe.bind(localAddress, promise);-->AbstractChannel.bind()-->doBind(localAddress);
--->NioServerSocketChannel.dobind()-->javaChannel().bind(localAddress, config.getBacklog());到这里可以看到是获取到了 java的原生serverSocketChannel,然后绑定端口
端口绑定之后,至此整个启动过程结束, 然后服务器进入---> NioEventLoop类protected void run() {} 这是一个无限循环代码,进行监听是否有task进来, runAllTask netty启动过程梳理:
1: 创建二个 EventLoopGroup线程池数组, 数组大小默认 CPU*2, 方便chooser选择线程池时提高性能
2: BootStrap将 boss设置为group属性, 将worker设置为childer属性
3: 通过 bind方法 启动服务器, 内部重要方法是 initAndRegister 和 dobind方法
3.1: initAndRegiser方法,会反射创建 NioServerSocketChannel,及相关的NIO对象,pipeline unsafe, 同时也为pipeline初始化了 head节点 tail节点
3.2: 初始化成功之后, dobind方法 最终是调用 NioServerSocketChannel 的dobind方法,,对JDK的 channel 和端口进行绑定,完成绑定之后,完成netty服务器所有启动,并开始后监听连接事件 二: netty接受请求过程源码分析
启动client,发送请求,---->NioEventLoop类的protected void run() {}--->processSelectedKeys();---(selector.selectedKeys() 这个方法返回所有注册在select选择器上的,有事件发生的通道的 sekectedKey集合,通过sekectedKey就可以反向获取到对应通道,然后就可以进行读写操作了,)
--->processSelectedKeysOptimized();这是请求发送有数据--->processSelectedKey(k, (AbstractNioChannel) a);---->unsafe.read();这是开始读取数据--->AbstractNioByteChannel.read()---pipeline.fireChannelRead(byteBuf);这里是循环读取数据
--->AbstractChannelHandlerContext.invokeChannelRead(head, msg);--->next.invokeChannelRead(m);----->channelRead(this, msg);--->ServerBootstrap.channelRead(ChannelHandlerContext ctx, Object msg)
--->childGroup.register(child)这一步是将child 注册到workerGroup事件循环组的线程池中,并添加一个监听器--->继续追reginster方法--->MultithreadEventLoopGroup.register(Channel channel)-->SlngleThreadEventLoop.register()
--->promise.channel().unsafe().register(this, promise);---->AbstractChannel.register()--->register0(promise);--->beginRead();---.doBeginRead();--->AbstractNioChannel.doBeginRead() 到这里客户端的连接完成了,接下来是监听读事件 netty接受请求过程梳理:
总体流程: 接受连接--->创建一个新的NioSocketChannel--->注册到一个workerEventLoop上---> 注册select Read事件
1: 服务器 轮询Accept事件, 获取事件后调用unsafe的read方法
2: doReadMessages 用于创建NioSocketChannel,这个对象包装JDK的NioChannel客户端
3: 随后执行 pipeline.fireChannelRead方法,开始读取数据 三: ChannelPipeline ChannelHandler ChannelHandlerContext 三者之间的关系

最新文章

  1. ResultSet用法集锦
  2. yii隐藏域的使用方法
  3. 腾讯云CentOS 安装MediaWiki
  4. Mysql复制-Slave库设置复制延迟
  5. Github 学习
  6. kali 更新源
  7. asp.net的decimal保留两位小数
  8. Java实现直接插入查找
  9. ALV DataChange EVENT
  10. Memory Limits for Windows and Windows Server Releases
  11. java学习笔记——IO部分(遍历文件夹)
  12. CSS3 3D环境实现立体 魔方效果代码
  13. Jmeter使用JDBC请求简介
  14. markdown 数学公式
  15. 附录A application.properties配置项
  16. 补充:MySQL经典45道题型
  17. 浅谈js抽象工厂模式
  18. <Codis><JedisPool><DeadLock>
  19. java字节流复制文件
  20. (转) mysql之status和variables区别及用法详解

热门文章

  1. 渗透测试神器Cobalt Strike的使用
  2. XCTF-ics-05
  3. 40 图 |我用 Mac M1 玩转 Spring Cloud
  4. h5实现电子签名
  5. 安装MySQL后,需要调整的10个性能配置项
  6. 爬虫:HTTP请求与HTML解析(爬取某乎网站)
  7. Django 请求和响应 request return
  8. VS·卸载进程卡死"正在配置您的系统,这可能需要一些时间"
  9. XSF /如何使用xrandr
  10. 搭建LAMP环境部署Nextcloud私人网盘