一、Netty的整体结构和源码结构

1. Core层

提供底层网络通信的通用抽象和实现,包括可扩展的事件模型、通用的通信API和支持零拷贝的ByteBuf等。

common模块是Netty的核心基础包,提供丰富的工具类,其他模块都需要依赖该模块。常用的包括:通用工具类和自定义并发包
通用工具类:包括定时器工具TimerTask、时间轮HashWheelTimer等
自定义并发包:增强的FastThreadLocal等

buffer模块中,Netty自己实现的了一个更为完备的ByteBuf工具类,用作网络通信的数据载体,该类是对Java ByteBuffer的完美替代品,解决了ByteBuffer长度固定造成的内存浪费,更安全地更改了Buffer的容量。同时Netty对ByteBuf进行了很多优化,包括缓存池化、减少数据拷贝的CompositeByteBuf 等

resolver模块,提供一些有关基础设施的解析工具,包括IP Address、Hostname、DNS 等。

2. Protocal Support协议支持层

包含主流协议的编码实现,如Http、SSL、Protobuf、压缩、大文件传输、二进制等主流协议,同时支持自定义应用协议。

codec模块主要负责编解码工作,通过编解码实现原始字节数据与业务实体对象之间的相互转化。该模块包含开箱即用的编码器,包括:HTTP、HTTP2、Redis、XML等。同时该模块提供抽象编码类:ByteToMessageDecoder和ByteToMessageEncoder,通过继承这两个类可以自定义编解码器。

handler模块主要负责数据处理工作,本质上是handler的集合。该模块提供了开箱即用的ChannelHandler实现类,如:日志、IP过滤等,可以自行在pipeline中加入相应的ChannelHandler。

3. Transport Service传输服务层

提供网络传输能力的定义和实现方法,支持Socket、Http隧道、虚拟机管道等传输方式。

transport模块是Netty提供数据处理和传输的核心模块。该模块包含很多重要的接口:BootStrap、Channel、ChannelHandler、EventLoop、ChannelPipeLine等。

二、Netty的逻辑架构

Netty的逻辑架构可以分为网络通信层、事件调度层和服务编排层,每一层包含不同的核心组件,各层之间的关系如图:

1. 网络通信层

用于执行网络I/O操作,支持多种网络协议和I/O模型的连接操作。当网络数据读到内核缓冲区之后,会触发各种网络事件,这些事件灰分发给事件调度层处理。

BootStrap和BootServerStrap组件

两个组件都是辅助Netty程序的启动、初始化和服务连接。BootStrap用于客户端连接远端服务器,只绑定一个EventLoopGroup,BootServerStrap用于服务端启动绑定本地端口,分别绑定Boss和Worker两个EventLoopGroup,Boss会不停地接收新的连接,然后将连接分配给Worker处理

BootStrap是整个Netty的入口,串联了Netty所有核心组件的初始化工作。

Channel组件

网络通信的载体,提供基本的API用于网络I/O操作,包括:register、bind、connect、read、write、flush等,

以JDK Channel为基础,进行了更高层次的抽象,屏蔽了底层的Socket。

channel的生命周期包含不同的状态,每个状态会绑定相应的事件回调,对应的事件由事件调度层进行处理。

2. 事件调度层

通过Reactor线程模型对各类事件进行聚合处理,通过Selector主循环线程集成多种事件,实际的业务处理逻辑交由服务编排层的Handler完成

EventLoopGroup和EventLoop组件

EventLoopGroup、EventLoop、Channel 的几点关系:

  • EventLoopGroup本质是一个线程池,包含一个或多个EventLoop。EventLoop用于处理Channel声明周期内的所有I/O事件,如accept、connect、read、write等
  • EventLoop同一时间会与一个线程绑定,每个EventLoop负责处理多个Channel
  • 每新建一个Channel,EventLoopGroup会选择一个EventLoop与其绑定,该Channel在生命周期内可以对EventLoop进行多次绑定和解绑

EventLoopGroup的实现类是NioEventLoopGroup,NioEventLoopGroup也是Netty中最被推荐的线程模型。NioEventLoopGroup继承自MultithreadEventLoopGroup,基于NIO模型开发

EventLoop是Netty Reactor线程模型的实际实现方法,通过不同的参数配置,可以支持三种Reactor线程模型

  • 单线程模型:EventLoopGroup 只包含一个 EventLoop,Boss 和 Worker 使用同一个EventLoopGroup;
  • 多线程模型:EventLoopGroup 包含多个 EventLoop,Boss 和 Worker 使用同一个EventLoopGroup;
  • 注册多线程模型:EventLoopGroup 包含多个 EventLoop,Boss 是主 Reactor,Worker 是从 Reactor,它们分别使用不同的 EventLoopGroup,主 Reactor 负责新的网络连接 Channel 创建,然后把 Channel 注册到从 Reactor。

服务编排层

负责组装各类服务,是Netty的核心处理链,用以实现网络时间的动态编排和有序传播

ChannelPipeLine组件

负责编排组装各种ChannelHandler,通过双向链表将不同的ChannelHandler连接在一起。当I/O读写时间触发时,一次调用ChannelHandler列表对Channel的数据进行拦截和处理。

每一个新的Channel对应绑定一个新的ChannelPipeLine,因此ChannelPipeLine是线程安全的。一个ChannelPipeLine关联一个EventLoop,一个EventLoop绑定一个线程。

ChannelPipeline 中包含入站 ChannelInboundHandler 和出站 ChannelOutboundHandler 两种处理器。数据入站会有一系列ChannelInboundHandler 处理,再以相反的ChannelOutboundHandler 处理完后完成出站。

ChannelHandler和ChannelHandlerContext

ChannelHandler用于实际的业务处理逻辑,包括数据的编解码和其他转换工作,开发者只需要关心ChannelHandler的逻辑即可。

ChannelHandlerContext 用于保存 ChannelHandler 上下文,包含了 ChannelHandler 生命周期的所有事件,如 connect、bind、read、flush、write、close 等,可以实现ChannelHandler之间的交互。

每创建一个Channel就会绑定一个新的ChannelPipeLine,ChannelPipeLine每加入一个ChannelHandler都会绑定一个ChannelHandlerContext。

组件关系梳理

  1. 服务端启动初始化时有 Boss EventLoopGroup 和 Worker EventLoopGroup 两个组件,其中 Boss 负责监听网络连接事件。当有新的网络连接事件到达时,则将 Channel 注册到 Worker EventLoopGroup。
    Worker EventLoopGroup 会被分配一个 EventLoop 负责处理该 Channel 的读写事件。每个 EventLoop 都是单线程的,通过 Selector 进行事件循环。
  2. 当客户端发起 I/O 读写事件时,服务端 EventLoop 会进行数据的读取,然后通过 Pipeline 触发各种监听器进行数据的加工处理。
  3. 客户端数据会被传递到 ChannelPipeline 的第一个 ChannelInboundHandler 中,数据处理完成后,将加工完成的数据传递给下一个 ChannelInboundHandler。
  4. 当数据写回客户端时,会将处理结果在 ChannelPipeline 的 ChannelOutboundHandler 中传播,最后到达客户端。
    以上便是 Netty 各个组件的整体交互流程,你只需要对每个组件的工作职责有所了解,心中可以串成一条流水线即可,具体每个组件的实现原理后续课程我们会深入介绍。

Netty学习二:Netty整体框架相关推荐

  1. Netty学习1——Netty的核心组件

    Netty的核心组件 Netty的主要构件块:Channel.回调.Future.事件和ChannelHandler 1.Channel Channel是Java NIO的一个基本构造. 它代表一个到 ...

  2. spring boot 学习(二)spring boot 框架整合 thymeleaf

    spring boot 框架整合 thymeleaf spring boot 的官方文档中建议开发者使用模板引擎,避免使用 JSP.因为若一定要使用 JSP 将无法使用. 注意:本文主要参考学习了大神 ...

  3. Netty学习记录-初步认识Netty及I/O模型

    Netty学习记录 Netty简介 Netty特征 Netty架构结构图 Netty如今使用的场景 IO了解 BIO: BIO演变的NIO的过程 NIO: NIO三大核心(重点) NIO非阻塞网络编程 ...

  4. Struts2框架学习(二) Action

    Struts2框架学习(二) Action Struts2框架中的Action类是一个单独的javabean对象.不像Struts1中还要去继承HttpServlet,耦合度减小了. 1,流程 拦截器 ...

  5. Netty,Tcp,socket的java框架,netty学习

    最新更新,报文发送,机器终端(车)与服务端 先学习一下基本内容,以下是基于基本内容 互相转换:byte(字节,字节是数字单位,他的数组是十进制内容),bit(二进制内容,不用操心这部分),十六进制0x ...

  6. Netty学习笔记二网络编程

    Netty学习笔记二 二. 网络编程 1. 阻塞模式 阻塞主要表现为: 连接时阻塞 读取数据时阻塞 缺点: 阻塞单线程在没有连接时会阻塞等待连接的到达,连接到了以后,要进行读取数据,如果没有数据,还要 ...

  7. Netty学习笔记(二) 实现服务端和客户端

    在Netty学习笔记(一) 实现DISCARD服务中,我们使用Netty和Python实现了简单的丢弃DISCARD服务,这篇,我们使用Netty实现服务端和客户端交互的需求. 前置工作 开发环境 J ...

  8. Netty学习笔记(二)Netty服务端流程启动分析

    先贴下在NIO和Netty里启动服务端的代码 public class NioServer { /*** 指定端口号启动服务* */public boolean startServer(int por ...

  9. Netty学习笔记:二、NIO网络应用实例-群聊系统

    实例要求: 编写一个NIO群聊系统,实现服务器端和多个客户端之间的数据简单通讯(非阻塞): 实现多人群聊: 服务器端:可以监测用户上线.离线,并实现消息转发功能: 客户端:通过channel可以无阻塞 ...

最新文章

  1. 桐城中学2021高考成绩查询,桐城中学2019高考成绩喜报、一本二本上线情况
  2. 专访:经历了时间检验的不仅是论文,还有唐杰自己 | SIGKDD 2020时间检验奖
  3. Linuc C 编程实例1
  4. IOS初级:UIScrollView UIPageControl
  5. 分布式系统服务器要求,浅谈分布式系统
  6. C/C++无限关机(提权例子)
  7. 求叶节点带权路径长度之和
  8. mysql 10048 linux_解决Can't connect to MySQL server on 'localhost' (10048)
  9. 写出质量好软件的75条体会-转载篇
  10. 0433-Kerberos环境下Impala Daemon在CDH5.15版本中KRPC端口27000异常分析
  11. 基于pytorch使用LSTM进行虎年春联生成
  12. matlab mcc-m,【matlab】matlab中 mcc、mbuild和mex命令详解
  13. MFC 加载并显示图片
  14. 使用 python 创建更改 word 文档
  15. vs2013中带命令行参数的调试方法
  16. edge不能打开html网页,Win10系统edge浏览器无法打开网页的解决方法
  17. 关于mysql使用 判断null 和 空字符串
  18. Android 自定义进度加载动画
  19. NIO 与 epoll
  20. 支付系统架构设计----整体结构图

热门文章

  1. python泊松分布_常见概率分布的Python实现
  2. QQ文件及文件夹的一些知识
  3. IntelliJ IDEA设置系列(五):类代码模板自定义(注释)
  4. Note: Bimodal Content Defined Chunking for Backup Streams
  5. wchar_t的用法
  6. 工业交换机冗余什么意思?
  7. linux系统读取plc状态,Linux系统下上位机通讯协议及PLC冗余系统组态-工业支持中心-西门子中国...
  8. MySql计算两个日期的时间差函数
  9. JavaScript头像图片上传插件支持上传类型大小尺寸验证
  10. c++未定义的引用问题总结