欢迎来到皮皮网网首页

【防58到家源码】【quill 源码模式】【志汇源码】netty-io源码分析

来源:tp源码 时间:2024-11-25 03:57:48

1.Netty原理-从NIO开始
2.一个SDK给我干懵逼了?大厂的码分SDK就这? Netty 版本的跃迁史
3.上为什么没人用t-io?
4.Netty基础篇2-Netty核心模块组件

netty-io源码分析

Netty原理-从NIO开始

       Netty是基于NIO的异步通信框架(曾经引入过AIO,后来放弃),故要说Netty原理我们要先从NIO开始。

        NIO 是JAVA在JDK4中引入的同步非阻塞通信模型,在NIO出现之前(JDK4之前)市场上只有一个BIO模型顾名思义BLOCKING IO (同步阻塞通信模型)

        BIO(BLOCKING I/O):

        BIO 为一个连接 一个线程的模式,当有连接时服务器会开启一个线程来处理请求

        若此请求啥都不想干此时线程会怎么样?

        此线程会进入阻塞模式(BLOCKING)!---啥也不干,干等着zzZZ~

        这种一连接,一线程的模式会造成服务器资源不必要的开销并且在大量连接访问时 服务器会发生什么?车道(线程)不足,车太多--我堵车了

        由此就出现了NIO

        ↓

        NIO(new/NONBLOCKING I/O):

        NIO为同步非阻塞通信模型,Select(多路复用器)为此模型的核心,实现了多个连接一个线程

        当有客户端连接请求时 此连接请求会被注册至select上,当select检测到此连接有I/O请求时才会打开一个线程去对此I/O请求进行处理-----单线程模型

        这个时候有人问了:这么多操作都在一个线程里,线程忙不过来怎么办?

        此时 由于网络请求、I/O读写、业务操作都在一个线程下,会导致在高并发的情况下存在性能瓶颈 于是乎有人就提出来 将业务操作丢到另一个线程怎么样?

        于是出现了第三种reactor模型-使用线程池进行操作网络请求、IO在一个线程,业务操作在另个一个线程 的业务分离----线程池模型

        从此图中可以看出此时 模型中使用一个线程池来进行网络请求、IO读取

        当读取完成后将业务操作绑定在线程池中另外的线程上-------网络IO与业务操作可以同步进行了!一切都完美了起来!

        但是!事情还没完!!这个时候又有人提出问题:在高并发的时候咋办?会不会有性能瓶颈

        因为网络IO是非常消耗CPU的,当网络请求与网络IO在同个线程中时,造CK的情况下单个线程并不足以支撑起所有的IO操作!因此也形成了在高并发状态下的性能瓶颈

        于是大佬们就想着,如果把IO拆出来让单个线程池去接收网络请求,用另一个线程池来进行IO与业务操作会不会更好

        于是第四种Reactor模型应运而生--主从Reactor多线程模型

        此模型中 mainReactor只用于接收网络请求,而subReactor中为一个线程池,线程池中每个线程上绑定一个select

        当mainReactor接收到请求时(一个描述符) 系统会生成一个新的描述符代表此连接生效,此时mainReactor会将新的描述符通过一个算法在线程池中选定一个线程 将此描述符绑定至此线程池上的select上,由此线程来对请求进行I/O 与业务操作

        从此百万连接高并发不是问题

        写到这 我们是不是想起了Netty的启动过程

        1、声明两个EventLoopGroup一个为boss(mainReactor)一个为worker(subReactor)

        EventLoopGroup(线程池)初始化的时候会生成(懒加载)指定数量的EventLoop(线程)若无指定 则会生成CPU数X2的线程

        2、声明一个启动辅助类Bootstrap并将EventLoopGroup注册到启动辅助类BootStrap上(bootStrap.group)

        接着再给bootstrap指定channel模型等属性,再添加上业务流水线(channelpipeline)并且在pipeline中添加上业务操作handler,(通过channelpipeline可以对传入数据为所欲为)

        3、绑定端口

        Netty启动完成

        这时候可能有人会问了:这和你上面说的reactor?NIO有啥关系?

        这个时候我们要这么看

        ↓

        若我们将boss与worker线程池设置为相同的一个线程池,那么会发生什么事?

        此时关注一下第三个Reactor模型时就会发现 当BOSS=WORKER时候 netty实现的就是第三种Reactor模型 使用线程池模型

        而当boss不等于worker的时候使用的就是第四种 主从多线程模型

        Netty就是基于Reactor模型来对NIO进行了易用化封装,从Netty源码中就可以看出来其实底层还都是NIO的接口

        此次处为自己读源码之后的理解 如有误请指正

        感恩

        反手拿下第一个赞

一个SDK给我干懵逼了?大厂的SDK就这? Netty 版本的跃迁史

       在日常开发中,我遇到过一件让我有些困惑的码分事情。那天,码分我在专注地编写 Bug 的码分防58到家源码时候,一位同事突然来找我,码分带来了一个非常特别的码分三方依赖库的 jar 包。这个 jar 包里包含了一些 Netty 的码分依赖,但问题是码分:无法确定具体是哪个版本的 Netty。我被这个“惊喜”搞得有点懵。码分

       于是码分,我接过同事递过来的码分quill 源码模式 jar 包,首先对它进行了解压。码分这个 jar 包的码分目录结构看起来与我所熟悉的某宝、某钉的码分 SDK 并不相同,没有常规的码分 pom 文件或 gradle 文件。我感到有些不解,志汇源码这些信息通常会明确指出依赖库的版本,但在这里却找不到踪迹。

       我开始怀疑,这可能是个不按套路出牌的黑科技。我反复检查了这个 jar 包的opencv java 源码目录,却始终找不到依赖库的坐标声明文件。这时,同事催促着要我帮忙解决问题,我只好暂时放下这个疑问,先试着通过版本试用的rtos dhcp 源码方法来确定这个 jar 包中 Netty 的具体版本。

       在查看这个 jar 包中的文件时,我发现其中包含了大量的 org.jboss.netty 依赖。我决定通过 mvnrepository.com 这个网站来搜索相关信息。输入 netty 关键字后,我发现搜索结果的前面大多数是 io.netty 的信息,直到第 7 个才出现了 org.jboss.netty 的信息。我进一步点击进入,发现提供的版本主要集中在 Netty3.0.x、3.1.x、3.2.x 系列。

       根据常识,项目中引用 Netty 通常都会选择最终稳定版本,因此我尝试在 jar 包的源文件中添加了一个 pom 文件,并使用 3.2..Final 这个版本进行测试。然而,在编译源代码时,我发现缺少了 org.jboss.netty.handler.codec./post/