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

Netty源码解析-请求处理与多路复用

摘要

Netty源码系列-NioEventLoop

1.1 Netty给Channel分配Nio Event Loop的规则

看下图,EventLoopGroup是线程组,每个EventLoop是一个线程,那么线程处理请求是怎么分配的呢?我们看一下源码
在这里插入图片描述

1.1.1 MultithreadEventLoopGroup.register方法

该方法是EventLoop注册Channel的方法,进入next()方法,就在下图最上面的一个方法。此方法负责选择一个NioEventLoop,进入super.next()方法。
在这里插入图片描述

1.1.2 super.next()方法

我们看到这里调用了MultithreadEventExecutorGroup的属性chooser的next()方法
在这里插入图片描述

点击chooser,我们找到它赋值的地方在构造方法里面,chooser的正是通过DefaultEventExecutorChooserFactory的newChooser获取的,
在这里插入图片描述

1.1.3 newChooser方法

进入newChooser方法,根据传入的executors长度是否2的指数返回不同的实现类,这里实现了一个策略模式。为什么要这么做呢?我们继续往下看
在这里插入图片描述

注意到这里isPowerOfTwo只有一行代码,为什么还有单独写一个方法呢,虽然只有一行代码但是不容易看懂,通过方法名我们一下就看懂了,这是一种可读性更好的实现方式

1.1.4 我们继续看chooser.next()方法

该方法来自于接口EventExecutorChooserFactory.EventExecutorChooser,有两个实现类GenericEventExecutorChooser和PowerOfTwoEventExecutorChooser,都是在DefaultEventExecutorChooserFactory中。
在这里插入图片描述

1.1.5 看两个实现类实现的有何不同

在这里插入图片描述

两者都是通过idx来获取索引值的,idx是递增的,这种模式类似轮询的方式。但是获取位置的方式不一样

  • GenericEventExecutorChooser,idx对executors.length取模,并取绝对值
  • PowerOfTwoEventExecutorChooser, idx对executors.length - 1做与运算确定位置,这种方式类似于HashMap中对桶位置运算的处理,与运算比数学运算快很多,但是只能在executors.length是2的指数的时候才可以发挥作用。

为什么不直接用idx呢
因为idx一直累加下去可能会越界,超出数组长度,所以需要取模或者做与运算的方式控制范围。

例如: executors.length = 2^4, 其二进制为10000,executors.length-1=01111。任何值与1111与运算都不会超过executors.length,同时任何小于executors.length的值和1111与运算都是其本身。这是这个特性才能实现这样的优化。

总结

在正常情况下我们还是使用GenericEventExecutorChooser来选择EventLoop,这里PowerOfTwoEventExecutorChooser对next方法做了优化,所以在EventLoop组长度是2的指数的时候我们可以更快的处理

1.2 多路复用怎么跨平台的

如下图,在不同的系统平台上,EventLoop如何跨平台呢?我们看一下Selector的源码(其他类似)
在这里插入图片描述

1.2.1 我们看一下new NioEventLoopGroup()

在这里插入图片描述

点进这个方法,继续进入,我们找到下面这个方法,看Selector来自SelectorProvider.provider
在这里插入图片描述

1.2.2 进入SelectorProvider.provider,这里的run方法里面有三个分支, 如下图。

  • 第一个是从配置的类加载provider
  • 第二个是从系统加载provider
  • 如果前两个都没有,看第三个sun.nio.ch.DefaultSelectorProvider.create,
    这个方法是jre虚拟机的方法,不同平台的jdk版本上,该方法不一样,Selector通过这种方式来实现跨平台
    在这里插入图片描述

下图是openjdk不同平台是Selector实现:
在这里插入图片描述

总结

跨平台通过java虚拟机实现,调用java虚拟机的方法,在不同的平台,该方法由不同的java虚拟机实现,这样实现跨平台,这蒸是java通过虚拟机实现跨平台的方式。


http://www.kler.cn/a/312252.html

相关文章:

  • 深入理解BERT模型配置:BertConfig类详解
  • 11张思维导图带你快速学习java
  • idea 解决缓存损坏问题
  • 10款PDF合并工具的使用体验与推荐!!!
  • Rust 整数
  • dapp获取钱包地址,及签名
  • uniapp中使用picker-view选择时间
  • vulhub搭建漏洞环境docker-compose up -d命令执行报错以及解决方法汇总
  • 信息收集常用指令
  • PDF样本册如何分享到朋友圈
  • Qt自定义信号、带参数的信号、lambda表达式和信号的使用
  • elemntui el-switch 在表格内改变状态失败,怎么复原???
  • 一文读懂SpringCLoud
  • 【RabbitMQ 项目】服务端数据管理模块之交换机管理
  • prometheus监控linux虚拟机
  • 操作系统迁移(CentOs -> Ubuntu)
  • Wacom 和 Splashtop 携手共赴 IBC 2024 展会,宣布向欧洲市场隆重推出 Wacom Bridge
  • XSS漏洞挖掘利用总结(附个人常用payload)
  • MyBatis 分批次执行(新增,修改,删除)
  • ROS激光雷达介绍
  • WPF中图片的宫格显示
  • TPDO触发条件如何满足?
  • AI学习指南深度学习篇-Adam的Python实践
  • 如何配置和使用自己的私有 Docker Registry
  • python的6种常用数据结构
  • 3.大语言模型LLM的公开资源(API、语料库、算法库)