当前位置: 首页 > news >正文

[笔记]netty随笔

记录使用过程中偶然发现的一些关键逻辑。先做记录,以后netty知识有一定体系再做整理

childGroup

服务器中有俩group,一个是parentGroup,负责处理链接请求,一个是childGroup,负责业务逻辑。

channelActive是在childGroup中触发的。

新建立链接后会触发channelActive这个事件,parent会将此事件打包成任务放到child的taskqueue中
offerTask:353, SingleThreadEventExecutor (io.netty.util.concurrent)
addTask:344, SingleThreadEventExecutor (io.netty.util.concurrent)
execute:836, SingleThreadEventExecutor (io.netty.util.concurrent)
execute0:827, SingleThreadEventExecutor (io.netty.util.concurrent)
execute:817, SingleThreadEventExecutor (io.netty.util.concurrent)
register:483, AbstractChannel$AbstractUnsafe (io.netty.channel)
register:89, SingleThreadEventLoop (io.netty.channel)
register:83, SingleThreadEventLoop (io.netty.channel)
register:86, MultithreadEventLoopGroup (io.netty.channel)
channelRead:215, ServerBootstrap$ServerBootstrapAcceptor (io.netty.bootstrap)
invokeChannelRead:444, AbstractChannelHandlerContext (io.netty.channel)
invokeChannelRead:420, AbstractChannelHandlerContext (io.netty.channel)
fireChannelRead:412, AbstractChannelHandlerContext (io.netty.channel)
channelRead:1410, DefaultChannelPipeline$HeadContext (io.netty.channel)
invokeChannelRead:440, AbstractChannelHandlerContext (io.netty.channel)
invokeChannelRead:420, AbstractChannelHandlerContext (io.netty.channel)
fireChannelRead:919, DefaultChannelPipeline (io.netty.channel)
read:97, AbstractNioMessageChannel$NioMessageUnsafe (io.netty.channel.nio)
processSelectedKey:788, NioEventLoop (io.netty.channel.nio)
processSelectedKeysOptimized:724, NioEventLoop (io.netty.channel.nio)
processSelectedKeys:650, NioEventLoop (io.netty.channel.nio)
run:562, NioEventLoop (io.netty.channel.nio)
run:997, SingleThreadEventExecutor$4 (io.netty.util.concurrent)
run:74, ThreadExecutorMap$2 (io.netty.util.internal)
run:30, FastThreadLocalRunnable (io.netty.util.concurrent)
run:842, Thread (java.lang)
child执行任务
channelActive:41, NettyHandler (com.example.demo.demos.service)
invokeChannelActive:262, AbstractChannelHandlerContext (io.netty.channel)
invokeChannelActive:238, AbstractChannelHandlerContext (io.netty.channel)
fireChannelActive:231, AbstractChannelHandlerContext (io.netty.channel)
channelActive:1398, DefaultChannelPipeline$HeadContext (io.netty.channel)
invokeChannelActive:258, AbstractChannelHandlerContext (io.netty.channel)
invokeChannelActive:238, AbstractChannelHandlerContext (io.netty.channel)
fireChannelActive:895, DefaultChannelPipeline (io.netty.channel)
register0:522, AbstractChannel$AbstractUnsafe (io.netty.channel)
access$200:429, AbstractChannel$AbstractUnsafe (io.netty.channel)
run:486, AbstractChannel$AbstractUnsafe$1 (io.netty.channel)
runTask:174, AbstractEventExecutor (io.netty.util.concurrent)
safeExecute:167, AbstractEventExecutor (io.netty.util.concurrent)
runAllTasks:470, SingleThreadEventExecutor (io.netty.util.concurrent)
run:569, NioEventLoop (io.netty.channel.nio)
run:997, SingleThreadEventExecutor$4 (io.netty.util.concurrent)
run:74, ThreadExecutorMap$2 (io.netty.util.internal)
run:30, FastThreadLocalRunnable (io.netty.util.concurrent)
run:842, Thread (java.lang)

从哪获取child?
ServerBootstrapAcceptor中会存储childGroup,通过这个childGroup以轮询这种负载均衡算法将任务设置到group中的一个loop里
在这里插入图片描述

在这里插入图片描述

ServerBootstrapAcceptor.childGroup何时何地设置?

<init>:186, ServerBootstrap$ServerBootstrapAcceptor (io.netty.bootstrap)
run:154, ServerBootstrap$1$1 (io.netty.bootstrap)
runTask:174, AbstractEventExecutor (io.netty.util.concurrent)
safeExecute:167, AbstractEventExecutor (io.netty.util.concurrent)
runAllTasks:470, SingleThreadEventExecutor (io.netty.util.concurrent)
run:569, NioEventLoop (io.netty.channel.nio)
run:997, SingleThreadEventExecutor$4 (io.netty.util.concurrent)
run:74, ThreadExecutorMap$2 (io.netty.util.internal)
run:30, FastThreadLocalRunnable (io.netty.util.concurrent)
run:842, Thread (java.lang)

child和parent为一个loop时,如何更换pipeline?
pipeline跟channel绑定,而不是与loop绑定

bossGroup设置为1就行了?
貌似只有一个channel在处理accept请求(如果服务端只开了一个端口监听服务),bossGroup设置多了也只会用一个loop。
这个观点还有待进一步验证

WEPollSelectorImpl

Selector

使用"轮询+同步阻塞"的方式处理channel中发生的事件

同步阻塞

底层使用微软的一套API阻塞线程,直到有新的事件到达

doSelect:111, WEPollSelectorImpl (sun.nio.ch)
lockAndDoSelect:129, SelectorImpl (sun.nio.ch)
select:146, SelectorImpl (sun.nio.ch)
select:68, SelectedSelectionKeySetSelector (io.netty.channel.nio)
select:879, NioEventLoop (io.netty.channel.nio)
run:526, NioEventLoop (io.netty.channel.nio)
run:997, SingleThreadEventExecutor$4 (io.netty.util.concurrent)
run:74, ThreadExecutorMap$2 (io.netty.util.internal)
run:30, FastThreadLocalRunnable (io.netty.util.concurrent)
run:842, Thread (java.lang)

在这里插入图片描述
阻塞状态结束后,io.netty.channel.nio.NioEventLoop#processSelectedKeysOptimized中会遍历io.netty.channel.nio.NioEventLoop#selectedKeys获取需要处理的事件

从NioEventLoop#selectedKeys取出的key的channel是netty中的类?

阻塞结束后用fd找到相应的channel然后进行处理?

parent在哪里将channel移交给child的selector?

设置att

netty的管道将以att的形式注册到selector

attach:458, SelectionKey (java.nio.channels)
register:212, SelectorImpl (sun.nio.ch)
register:236, AbstractSelectableChannel (java.nio.channels.spi)
doRegister:380, AbstractNioChannel (io.netty.channel.nio)
register0:508, AbstractChannel$AbstractUnsafe (io.netty.channel)
access$200:429, AbstractChannel$AbstractUnsafe (io.netty.channel)
run:486, AbstractChannel$AbstractUnsafe$1 (io.netty.channel)
runTask:174, AbstractEventExecutor (io.netty.util.concurrent)
safeExecute:167, AbstractEventExecutor (io.netty.util.concurrent)
runAllTasks:470, SingleThreadEventExecutor (io.netty.util.concurrent)
run:569, NioEventLoop (io.netty.channel.nio)
run:997, SingleThreadEventExecutor$4 (io.netty.util.concurrent)
run:74, ThreadExecutorMap$2 (io.netty.util.internal)
run:30, FastThreadLocalRunnable (io.netty.util.concurrent)
run:842, Thread (java.lang)

在这里插入图片描述

上个截图中使用javaChannel获取到java自带的channel,然后用这个自带的channel生成了一个key。其中有几点需要注意。
1、原生channel(this)+监听的事件(ops)+nettyChannel(att)+selector(sel)=key,同时这个key也会反过来注册到当前的原生channel上(addKey(k))
在这里插入图片描述

2、若当前原生channel已经注册到selector中,就不要重复生成了。findKey中会遍历当前原生channel的keys
在这里插入图片描述

在这里插入图片描述
这也间接说明一个channel可以绑定在多个selector上,但是同一个selector上不能绑定多个相同的channel,即使ops不同也不行

fdToKey

processUpdateQueue:131, WEPollSelectorImpl (sun.nio.ch)
doSelect:107, WEPollSelectorImpl (sun.nio.ch)
lockAndDoSelect:129, SelectorImpl (sun.nio.ch)
select:146, SelectorImpl (sun.nio.ch)
select:68, SelectedSelectionKeySetSelector (io.netty.channel.nio)
select:879, NioEventLoop (io.netty.channel.nio)
run:526, NioEventLoop (io.netty.channel.nio)
run:997, SingleThreadEventExecutor$4 (io.netty.util.concurrent)
run:74, ThreadExecutorMap$2 (io.netty.util.internal)
run:30, FastThreadLocalRunnable (io.netty.util.concurrent)
run:842, Thread (java.lang)

fd

生成文件描述符

<init>:130, ServerSocketChannelImpl (sun.nio.ch)
<init>:109, ServerSocketChannelImpl (sun.nio.ch)
openServerSocketChannel:72, SelectorProviderImpl (sun.nio.ch)
newChannel:63, NioServerSocketChannel (io.netty.channel.socket.nio)
<init>:89, NioServerSocketChannel (io.netty.channel.socket.nio)
<init>:82, NioServerSocketChannel (io.netty.channel.socket.nio)
<init>:75, NioServerSocketChannel (io.netty.channel.socket.nio)
newInstance0:-1, NativeConstructorAccessorImpl (jdk.internal.reflect)
newInstance:77, NativeConstructorAccessorImpl (jdk.internal.reflect)
newInstance:45, DelegatingConstructorAccessorImpl (jdk.internal.reflect)
newInstanceWithCaller:499, Constructor (java.lang.reflect)
newInstance:480, Constructor (java.lang.reflect)
newChannel:44, ReflectiveChannelFactory (io.netty.channel)
initAndRegister:310, AbstractBootstrap (io.netty.bootstrap)
doBind:272, AbstractBootstrap (io.netty.bootstrap)
bind:268, AbstractBootstrap (io.netty.bootstrap)
bind:253, AbstractBootstrap (io.netty.bootstrap)
init:58, DemoApplicationTests2 (com.example.demo)
main:33, DemoApplicationTests2 (com.example.demo)

设置selectedKeys

io.netty.channel.nio.NioEventLoop#selectedKeys与WEPollSelectorImpl中的selectedKeys是同一个对象。netty中会通过反射的方式将io.netty.channel.nio.NioEventLoop#selectedKeys设置到WEPollSelectorImpl中的selectedKeys。

run:228, NioEventLoop$4 (io.netty.channel.nio)
executePrivileged:776, AccessController (java.security)
doPrivileged:318, AccessController (java.security)
openSelector:213, NioEventLoop (io.netty.channel.nio)
<init>:146, NioEventLoop (io.netty.channel.nio)
newChild:183, NioEventLoopGroup (io.netty.channel.nio)
newChild:38, NioEventLoopGroup (io.netty.channel.nio)
<init>:84, MultithreadEventExecutorGroup (io.netty.util.concurrent)
<init>:60, MultithreadEventExecutorGroup (io.netty.util.concurrent)
<init>:52, MultithreadEventLoopGroup (io.netty.channel)
<init>:97, NioEventLoopGroup (io.netty.channel.nio)
<init>:92, NioEventLoopGroup (io.netty.channel.nio)
<init>:73, NioEventLoopGroup (io.netty.channel.nio)
<init>:53, NioEventLoopGroup (io.netty.channel.nio)
init:39, DemoApplicationTests2 (com.example.demo)
main:33, DemoApplicationTests2 (com.example.demo)

在这里插入图片描述

因为io.netty.channel.nio.NioEventLoop#selectedKeys与WEPollSelectorImpl中的selectedKeys是同一个对象,所以loop阻塞结束后,可以直接使用io.netty.channel.nio.NioEventLoop#selectedKeys获取WEPollSelectorImpl的结果

channel注册到selector

相关文章:

  • centos 7.4 docker
  • 【Spark源码分析】Spark的RPC通信二-初稿
  • 【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串
  • Vue 3 语法和特性
  • 在Next.js和React中搭建Cesium项目
  • 快递收发线上管理教程
  • Zookeeper 集群搭建过程中常见错误
  • Java设计模式之单例模式以及如何防止通过反射破坏单例模式
  • 基于多反应堆的高并发服务器【C/C++/Reactor】(下)
  • XML简介 (EXtensible Markup Language)
  • mybatis-plus阻止全表更新与删除
  • Wavesurfer.js绘制波形图
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • 软考高级难度排行榜,哪个科目相对较容易呢?
  • web前端游戏项目-堆木头游戏【附源码】
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • Debian下无root权限使用Python访问Oracle
  • Druid 在有赞的实践
  • Fastjson的基本使用方法大全
  • github指令
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • Just for fun——迅速写完快速排序
  • Nacos系列:Nacos的Java SDK使用
  • vue.js框架原理浅析
  • vue的全局变量和全局拦截请求器
  • 分布式熔断降级平台aegis
  • 观察者模式实现非直接耦合
  • 汉诺塔算法
  • 近期前端发展计划
  • 前端面试总结(at, md)
  • 算法-图和图算法
  • 译米田引理
  • HanLP分词命名实体提取详解
  • MPAndroidChart 教程:Y轴 YAxis
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • #{}和${}的区别?
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (3)选择元素——(17)练习(Exercises)
  • (6)添加vue-cookie
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (二)springcloud实战之config配置中心
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (五)c52学习之旅-静态数码管
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .netcore如何运行环境安装到Linux服务器
  • [ Linux ] git工具的基本使用(仓库的构建,提交)
  • [ 常用工具篇 ] AntSword 蚁剑安装及使用详解
  • [Android Pro] AndroidX重构和映射
  • [Android]How to use FFmpeg to decode Android f...
  • [Android]竖直滑动选择器WheelView的实现
  • [javaee基础] 常见的javaweb笔试选择题含答案