Netty是一个高性能、异步事件驱动的NIO框架,它提供了对TCP、UDP和文件传输的支持,做为一个异步NIO框架,Netty的全部IO操做都是异步非阻塞的,经过Future-Listener机制,用户能够方便的主动获取或者经过通知机制得到IO操做结果。数组
做为当前最流行的NIO框架,Netty在互联网领域、大数据分布式计算领域、游戏行业、通讯行业等得到了普遍的应用,一些业界著名的开源组件也基于Netty的NIO框架构建。性能优化
Netty架构分析网络
Netty 采用了比较典型的三层网络架构进行设计,逻辑架构图以下所示:多线程
第一层:Reactor 通讯调度层,它由一系列辅助类完成,包括 Reactor 线程 NioEventLoop 以及其父类、NioSocketChannel/NioServerSocketChannel 以及其父类、ByteBuffer 以及由其衍生出来的各类 Buffer、Unsafe 以及其衍生出的各类内部类等。该层的主要职责就是监听网络的读写和链接操做,负责将网络层的数据读取到内存缓冲区中,而后触发各类网络事件,例如链接建立、链接激活、读事件、写事件等等,将这些事件触发到 PipeLine 中,由 PipeLine 充当的职责链来进行后续的处理。架构
第二层:职责链 PipeLine,它负责事件在职责链中的有序传播,同时负责动态的编排职责链,职责链能够选择监听和处理本身关心的事件,它能够拦截处理和向后/向前传播事件,不一样的应用的 Handler 节点的功能也不一样,一般状况下,每每会开发编解码 Hanlder 用于消息的编解码,它能够将外部的协议消息转换成内部的 POJO 对象,这样上层业务侧只须要关心处理业务逻辑便可,不须要感知底层的协议差别和线程模型差别,实现了架构层面的分层隔离。并发
第三层:业务逻辑处理层,能够分为两类:框架
1.纯粹的业务逻辑处理,例如订单处理。异步
2.应用层协议管理,例如HTTP协议、FTP协议等。分布式
接下来,我从影响通讯性能的三个方面(I/O模型、线程调度模型、序列化方式)来谈谈Netty的架构。高并发
这里推荐一下个人Java架构学习群:479499375 ,群里有(Java高架构、分布式架构、高可扩展、高性能、高并发、性能优化、Spring boot、Redis、ActiveMQ、等学习资源)进群免费送给每一位Java小伙伴,无论你是转行,仍是工做中想提高本身能力均可以!
IO模型
Netty的I/O模型基于非阻塞I/O实现,底层依赖的是JDK NIO框架的Selector。
Selector提供选择已经就绪的任务的能力。简单来说,Selector会不断地轮询注册在其上的Channel,若是某个Channel上面有新的TCP链接接入、读和写事件,这个Channel就处于就绪状态,会被Selector轮询出来,而后经过SelectionKey能够获取就绪Channel的集合,进行后续的I/O操做。
线程调度模型
经常使用的Reactor线程模型有三种,分别以下:
1.Reactor单线程模型:Reactor单线程模型,指的是全部的I/O操做都在同一个NIO线程上面完成。对于一些小容量应用场景,可使用单线程模型。
2.Reactor多线程模型:Rector多线程模型与单线程模型最大的区别就是有一组NIO线程处理I/O操做。主要用于高并发、大业务量场景。
3.主从Reactor多线程模型:主从Reactor线程模型的特色是服务端用于接收客户端链接的再也不是个1个单独的NIO线程,而是一个独立的NIO线程池。利用主从NIO线程模型,能够解决1个服务端监听线程没法有效处理全部客户端链接的性能不足问题。
序列化方式
影响序列化性能的关键因素总结以下:
1.序列化后的码流大小(网络带宽占用)
2.序列化&反序列化的性能(CPU资源占用)
3.并发调用的性能表现:稳定性、线性增加、偶现的时延毛刺等
这里推荐一下个人Java架构学习群:479499375 ,群里有(Java高架构、分布式架构、高可扩展、高性能、高并发、性能优化、Spring boot、Redis、ActiveMQ、等学习资源)进群免费送给每一位Java小伙伴,无论你是转行,仍是工做中想提高本身能力均可以!
链路有效性检测
心跳检测机制分为三个层面:
1.TCP层面的心跳检测,即TCP的Keep-Alive机制,它的做用域是整个TCP协议栈;
2.协议层的心跳检测,主要存在于长链接协议中。例如SMPP协议;
3.应用层的心跳检测,它主要由各业务产品经过约定方式定时给对方发送心跳消息实现。
心跳检测的目的就是确认当前链路可用,对方活着而且可以正常接收和发送消息。做为高可靠的NIO框架,Netty也提供了基于链路空闲的心跳检测机制:
1.读空闲,链路持续时间t没有读取到任何消息;
2.写空闲,链路持续时间t没有发送任何消息;
3.读写空闲,链路持续时间t没有接收或者发送任何消息。
零拷贝
· 使用getByte(int index)方法来实现随机访问
· 使用双指针的方式实现顺序访问
· Netty主要实现了HeapChannelBuffer,ByteBufferBackedChannelBuffer,与Zero Copy直接相关的CompositeChannelBuffer类
Netty 的 Zero-copy 体如今以下几个个方面:
l Netty 提供了 CompositeByteBuf 类, 它能够将多个 ByteBuf 合并为一个逻辑上的 ByteBuf, 避免了各个 ByteBuf 之间的拷贝。
l 经过 wrap 操做, 咱们能够将byte[] 数组、ByteBuf、ByteBuffer等包装成一个 Netty ByteBuf 对象, 进而避免了拷贝操做。
l ByteBuf 支持 slice 操做,所以能够将 ByteBuf 分解为多个共享同一个存储区域的ByteBuf, 避免了内存的拷贝。
l 经过 FileRegion 包装的FileChannel.tranferTo 实现文件传输, 能够直接将文件缓冲区的数据发送到目标 Channel, 避免了传统经过循环 write 方式致使的内存拷贝问题。