这里提出关于架构的几个问题,但不会给出答案,毕竟本人也是在不断探索中,并非权威。旨在引起思考,自己也会每日自省。
1、架构,是创造,还是选择?
2、架构的目的,到底是什么?
3、有哪些制约条件?
4、影响、决定架构的因素?
IO相关:
Linux IO模式及 select、poll、epoll详解
这里只列一张图,用于简要说明常用的I/O方法和对比:
Netty官网,醒目位置描述:
Netty is an asynchronous event-driven network application frameworkfor rapid development of maintainable high performance protocol servers & clients.Netty is a NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients. It greatly simplifies and streamlines network programming such as TCP and UDP socket server.
翻译过来:
Netty是一个异步事件驱动网络应用框架,用于快速开发可维护的高性能协议服务器和客户端。
总结起来关键包括两点:
除此之外,大家更了解的是Netty:
1、易用:详细记录的 Javadoc,用户指南和示例;只依赖JDK,没有其他依赖。
2.高性能:吞吐量更高、延迟更低、减少资源消耗、最小化不必要的内存复制。
3、安全性:完整的SSL/TLS和Start TLS支持;
4、以及较高的社区活跃度。
下图是Netty官网的最新架构图:
从架构图可见,Netty可以分为Core、Transport Services、Protocol Support三大模块。
核心模块,支持零拷贝的富字节缓冲区、通用的通信API、可扩展事件模型。
零拷贝(Zero-Copy)是一个比较重要的概念,解决了网络传输时多次数据拷贝的问题。Wiki中对零拷贝的定义如下:
"Zero-copy" describes computer operations in which the CPU does not perform the task of copying data from one memory area to another. This is frequently used to save CPU cycles and memory bandwidth when transmitting a file over a network.
翻译过来:
零拷贝技术是指计算机执行操作时,CPU不需要先将数据从某处内存复制到另一个特定区域。这种技术通常用于通过网络传输文件时节省 CPU 周期和内存带宽。
零拷贝解决什么问题:
想要更详细地了解Linux I/O和零拷贝相关内容,可以看这边腾讯的文章:Linux I/O 原理和 Zero-copy 技术全面揭秘。
传输服务,
这一块稍有些难以理解,对最上层的Socket大家都有使用,但对Http隧道 和 虚拟机内管道了解不多。简单来说,HTTP Tunnel是HTTP1.1引入的一个功能,用以解决明文的HTTP Proxy无法代理跑在TLS中的流量(即https)的问题,同时提供了作为任意流量的TCP通道的能力。
定义可查看:rfc2817 和 rfc7540。应用实例:HTTP Tunnel的应用实例
关于管道,目前没有查到特别明确的资料。不过初步分析是JVM的管道,用于处理进程间通讯。进程间常用的通讯方式可以初步划分为管道、共享内存、Socket三种。
目前从官网可下载的最新版本是4.1.60(发布于2021-03-09)。不过其实netty5在2016年就已经发布,但被官方舍弃,相关说明可以看作者的这个issue: Remove master branch #4466,原因如下:
而3.x 和 4.x中,4.x是官方推荐版本,也可以看到一直在维护更新,所以以4.x版本作为分析目标。
目前项目中使用的实际上是4.1.25版本,但这里会选择相对新一点的4.1.50版本进行分析。Maven引入方式如下:
我们对比一下两个版本之间的结构差异:
从结构上看,增加了native-image.io.netty包,并且在native下增加了libnetty_resolver_dns_native_macos_x86_64.jnilib 和 libnetty_transport_native_epoll_aarch_64.so两个库文件。可以看到是对macos 和 aarch_64架构的支持。
从上面也可以看到,源码结构并没有发生变化。按照包结构:
启动类所在包,Netty中服务端和客户端的启动类不同,这点切记!bootstrap中主要包括两类:bootstrap和config。channelFactory接口已标记为废弃,乱入了一个FailedChannel。
涉及底层的缓冲处理。上面Netty的特性和零拷贝概念,以及buffer包下的代码量都可以看到,这是很重的一块内容。
管道,用于连接字节缓冲区Buf和另一端的实体,这个实例可以是Socket,也可以是File, 在Nio网络编程模型中, 服务端和客户端进行IO数据交互(得到彼此推送的信息)的媒介。
Netty对Jdk原生的ServerSocketChannel
进行了封装和增强,成了NioXXXChannel
, 相对于原生的JdkChannel, Netty的Channel增加了如下的组件:
处理器,是Reactor模型中的重要角色。再引用一下这张图:
在Reactor经典模型中,Reactor查询到NIO就绪的事件后,分发到Handler,由Handler完成NIO操作和计算的操作。
Handler主要的操作为Channel缓存读、数据解码、业务处理、写Channel缓存,然后由Channel(代表client)发送到最终的连接终端。
分解器,针对Host、Addres、dns进行处理。
本篇介绍Netty的架构和代码结构,下一篇将通过一个demo来分析Netty运行的主流程,并结合reactor模型进行解析。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。