手把手教你调试Netty创建连接流程源码

JavaEdge

共 1501字,需浏览 4分钟

 ·

2020-12-29 14:09


  点击上方“JavaEdge”,关注公众号

设为“星标”,好文章不错过!

boss thread

  • NioEventLoop 中的 selector轮询创建连接事件 (ОР_АССЕРT)

  • 创建 socket channel

  • 初始化 socket channel 并从 worker group 中选择一个 NioEventLoop

worker thread

  • 将socket channel注册到选择的NioEventLoop的selector

  • 注册读事件(OP_ READ)到selector 上

接收连接请求的处理本质是对 OP_ACCEPT 的处理,即在 NioEventLoop 中,因为注册到了NioEventLoop的 selector。
分别调试启动 EchoServer 和 EchoClient

  • 跳至对应 handler

  • 当前为 bosseventloop,不是 workereventloop

    • 所以这里 false,又来到注册

    • 创建完连接后了,已经可以开始接收数据了,即准备读数据了

      最后观察下 server 的日志信息
      前5行都是服务启动,后面的就是为了创建连接

    服务启动过程多了个 bind 过程,且只绑定了一个接口,而对于下面的创建连接过程它有两个端口:客户端端口+server 监听的端口,这就是 socketChannel

接收连接的核心代码

// 阻塞轮询。非阻塞轮询。超时等待轮询selector.select()/ selectNow()/select(timeoutMillis) 发现 OP_ACCEPT 事件,处理:SocketChannel socketChannel = serverSocketChannel.accept()selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this);selectionKey.interestOps(OP_READ);


创建连接的初始化和注册是通过pipeline.fireChannelReadServerBootstrapAcceptor中完成

第一次Register并非监听OP_READ,而是0

selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this)


最终监听OP_READ是通过"Register"完成后的fireChannelActive
(io.netty.channel.AbstractChannel.AbstractUnsafe#register0)触发

Worker’s NioEventLoop是通过Register操作执行来启动。

接受连接的读操作,不会尝试读取更多次(16次)。
因为无法知道后续是否还有连接,不可能一直尝试。


往期推荐


大厂如何解决数值精度/舍入/溢出问题

大厂数据库事务实践-事务生效就能保证正确回滚?

线上问题事迹(一)数据库事务居然都没生效?

硬核干货:HTTP超时、重复请求必见坑点及解决方案

给大忙人们看的Java NIO教程之Channel





目前交流群已有 800+人,旨在促进技术交流,可关注公众号添加笔者微信邀请进群


喜欢文章,点个“在看、点赞、分享”素质三连支持一下~

浏览 32
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报