[笔记]netty随笔

news2025/2/3 15:18:10

记录使用过程中偶然发现的一些关键逻辑。先做记录,以后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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1328745.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Chrome浏览器http自动跳https问题

现象&#xff1a; Chrome浏览器访问http页面时有时会自动跳转https&#xff0c;导致一些问题。比如&#xff1a; 开发阶段访问dev环境网址跳https&#xff0c;后端还是http&#xff0c;导致接口跨域。 复现&#xff1a; 先访问http网址&#xff0c;再改成https访问&#xf…

Ubuntu 常用命令之 exit 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 exit命令在Ubuntu系统下用于结束一个终端会话。它可以用于退出当前的shell&#xff0c;结束当前的脚本执行&#xff0c;或者结束一个ssh会话。 exit命令的参数是一个可选的整数&#xff0c;用于指定退出状态。如果没有指定&#…

论文阅读——llava

Visual Instruction Tuning LLaVA 指令智能体分为两类&#xff1a;端到端的&#xff0c;通过LangChain[1]/LLM[35]协调各种模型的系统。 数据集生成用GPT辅助生成的&#xff0c;具体不写了。 模型结构&#xff1a; input image Xv LLM&#xff1a;Vicuna visual encoder&a…

docker学习(十一、Redis集群存储数据方式)

文章目录 一、集群数据存储1.单机连接集群问题2.集群方式连接redis存储数据 二、 查看集群信息 docker搭建Redis集群相关知识&#xff1a; docker学习&#xff08;九、分布式存储亿级数据知识&#xff09; docker学习&#xff08;十、搭建redis集群&#xff0c;三主三从&#x…

java easyexcel上传和下载数据

安装依赖 easyexcel官方文档 <!--通过注解的方式导出excel--><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.1</version></dependency>注意踩坑&#xff1a;easyexcel会…

vm 如何桥接模式

1、配置桥接模式 2、进入虚拟机配置 网卡 ip 根据自己的实际情况。 如果桥接的有限以太网外部连接了 路由器&#xff0c;可以直接选择 DHCP 自动分配。 如果 路由器没有帮你分配 ip 地址&#xff0c;建议设置 路由器&#xff0c; 或者直接手动配置 ip地址。 如果没有就自己手…

Go语言与HTTP/2协议的实践探索

随着互联网技术的发展&#xff0c;HTTP/2协议逐渐成为主流。Go语言作为一种高效、简洁的编程语言&#xff0c;与HTTP/2协议的结合具有很大的潜力。本文将探讨Go语言与HTTP/2协议的实践探索。 一、HTTP/2协议的优势 HTTP/2协议相比HTTP/1.1协议&#xff0c;具有以下优势&#…

Modbus-TCP数据帧

Modbus-TCP基于4种报文类型 MODBUS 请求是客户机在网络上发送用来启动事务处理的报文MODBUS 指示是服务端接收的请求报文MODBUS 响应是服务器发送的响应信息MODBUS 证实是在客户端接收的响应信息 Modbus-TCP报文: 报文头MBAP MBAP为报文头&#xff0c;长度为7字节&#xff0c…

DshanMCU-R128s2 ADC 按键配置方法

FreeRTOS平台上使用的按键为ADC-KEY&#xff0c;采用的ADC模块为GPADC。 按键功能驱动的实现是通过ADC分压&#xff0c;使每个按键检测的电压值不同&#xff0c;从而实现区分不同的按键。按下或者弹起中断之后&#xff0c;通过中断触发&#xff0c;主动检测当前电压识别出对应…

金蝶云星空执行部署包后业务对象会被标记上部署包的开发码

文章目录 金蝶云星空执行部署包后业务对象会被标记上部署包的开发码 金蝶云星空执行部署包后业务对象会被标记上部署包的开发码 会被标记成开发码的业务对象包括以下&#xff1a; 新增的业务对象&#xff0c;扩展的业务对象 --查询二开的元数据打包 FPACKAGEID不为空&#xff…

阻塞 IO(BIO)

文章目录 阻塞 IO(BIO)模型等待队列头init_waitqueue_headDECLARE_WAIT_QUEUE_HEAD 等待队列项使用方法驱动程序应用程序模块使用参考 阻塞 IO(BIO) 模型 等待队列是内核实现阻塞和唤醒的内核机制。 等待队列以循环链表为基础结构&#xff0c;链表头和链表项分别为等待队列头和…

loki-日志

一、loki Github ELK虽然功能丰富&#xff0c;但规模复杂&#xff0c;资源占用高&#xff0c;操作苦难&#xff0c;很多功能往往用不上&#xff0c;loki 受 prometheus 启发的水平可扩展、高可用、多租户日志聚合系统&#xff0c;它的设计非常经济高效且易于操作&#xff0c;…

Linux:动态链接

文章目录 动态链接共享库静态库的缺点共享库共享库是以两种不同的方式来“共享”第一种&#xff1a;共享这个so文件中的代码和数据第二种&#xff1a;共享库的.text 节的副本可以被不同的正在运行的进程共享 动态链接过程 动态链接的用武之地和使用场景分发软件构建高性能 Web …

初识Docker-什么是docker

Docker是一个快速交付应用、运行应用的技术 目录 一、Docker 二、运用场景 一、什么是Docker&#xff1f;它的作用是什么&#xff1f; Docker如何解决大型项目依赖关系复杂&#xff0c;不同组件依赖的兼容性问题? Docker允许开发中将应用、依赖、函数库、配置一起打包&…

服装店收银系统 一种私域运营的神器

私域运营是指通过建立和管理自己的客户数据库来实现精细化营销和客户关系管理。服装店收银系统是门店私域运营的神器之一&#xff0c;服装店收银系统可以帮助店主收集客户的购买信息、消费偏好等数据&#xff0c;从而更好地了解客户需求并进行个性化营销。 以下是一些服装店收银…

用Minikube 搭建一个单机k8s玩玩

Minikube 介绍 Minikube是一款单机搭建和管理Kubernetes集群的工具。与Kind 类似&#xff0c;但是个人认为比Kind 好用 Minikube 安装 mac如果安装了 Homebrew&#xff0c;直接执行以下命令安装minikube brew install minikubemac没有安装Homebrew,需要到官网下载选择系统配置…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之TextInput输入框组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之TextInput输入框组件 一、操作环境 操作系统: Windows 10 专业版 IDE:DevEco Studio 3.1 SDK:HarmonyOS 3.1 二、TextInput 接口 TextInput(value?:{placeholder?: ResourceStr, tex…

HackTheBox - Medium - Linux - Jupiter

Jupiter Jupiter 是一台中等难度的 Linux 机器&#xff0c;它有一个使用 PostgreSQL 数据库的 Grafana 实例&#xff0c;该数据库在权限上过度扩展&#xff0c;容易受到 SQL 注入的影响&#xff0c;因此容易受到远程代码执行的影响。一旦站稳脚跟&#xff0c;就会注意到一个名…

被有道云笔记成功劝退拥抱Joplin(Joplin使用过程遇到的问题)

本人职业程序员&#xff0c;培训讲师&#xff08;技术类&#xff09;、活动主持人&#xff0c;对多端阅读是有些需求的&#xff0c;平时习惯墨水平板、手机和笔记本电脑登录着有道云笔记。其实本人对内容比较重视&#xff0c;对有道云笔记提供的什么AI服务、PDF转Word等功能是没…

企业级“RAS”的数据平台如何炼成?

从“看报表”到“数据分析结果直接投入运营”&#xff0c;数字化正在深入企业经营&#xff0c;数据系统正在成为核心生产系统。相应的&#xff0c;企业对“作业挂了”、“系统崩了”、“算不出来”的容忍度越来越低——只有足够稳定、可靠、专业的数据系统&#xff0c;才能及时…