Netty
Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.
使用场景 zk ,redis proxy ,dubbo等
more : https://netty.io/
版本特征
3.x
4.x RECOMMENDED VERSION
5.x ABANDONED VERSION - NOT SUPPORTED
more : https://netty.io/wiki/user-guide.html
三个问题
- IO模型 (NIO)
- 数据协议(零拷贝、序列化框架)
- 线程模型(锁)
高性能之道
异步非阻塞通信
NIO、多路复用I/O(JNI epoll)
http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf
JDK1.4 提供了对非阻塞 IO(NIO)的支持,JDK1.5_update10 版本使用 epoll 替代了传统的 select/poll,极大的提升了 NIO 通信的性能
零拷贝
Zero-Copy describes computer operations in which the CPU does not perform the task of copying data from one memory area to another.
直接堆外内存
Netty 的接收和发送 ByteBuffer 采用 DIRECTBUFFERS,使用堆外直接内存进行 Socket 读写,不需要进行字节缓冲区的二次拷贝
如果使用传统的堆内存分配,当我们需要将数据通过socket发送的时候,就需要从堆内存拷贝到直接内存,然后再由直接内存拷贝到网卡接口层。
Netty提供的直接Buffer,直接将数据分配到内存空间,从而避免了数据的拷贝,实现了零拷贝。
组合Buffer对象
Netty 提供了组合 Buffer 对象,可以聚合多个 ByteBuffer 对象,用户可以像操作一个 Buffer 那样方便的对组合 Buffer 进行操作,避免了传统通过内存拷贝的方式将几个小 Buffer 合并成一个大的 Buffer。
文件传输
Netty 的文件传输采用了 transferTo 方法,它可以直接将文件缓冲区的数据发送到目标 Channel,避免了传统通过循环 write 方式导致的内存拷贝问题。(Linux对零拷贝的支持)
堆外内存的内存池
为了尽量重用缓冲区,Netty 提供了基于内存池的缓冲区重用机制
高效的 Reactor 线程模型
Reactor 单线程模型
Reactor 多线程模型
IO pool
主从 Reactor 多线程模型
Acceptor pool
无锁化的串行设计理念
Netty 的 NioEventLoop 读取到消息之后,直接调用 ChannelPipeline 的 fireChannelRead(Object msg),只要用户不主动切换线程,一直会由 NioEventLoop 调用到 用户的 Handler,期间不进行线程切换,这种串行化处理方式避免了多线程操作导致的锁的 竞争,从性能角度看是最优的。
高效的并发编程
- volatile 的大量、正确使用
- CAS 和原子类的广泛使用
- 线程安全容器的使用
- 通过读写锁提升并发性能
高性能的序列化框架
影响序列化性能的关键因素
- 序列化后的码流大小(网络带宽的占用)
- 序列化&反序列化的性能(CPU 资源占用)
- 是否支持跨语言(异构系统的对接和开发语言切换)
通过扩展 Netty 的编解码接口,用户可以实 现其它的高性能序列化框架
灵活的 TCP 参数配置能力
SO_RCVBUF 和 SO_SNDBUF
通常建议值为 128K 或者 256K
SO_TCPNODELAY
NAGLE 算法通过将缓冲区内的小封包自动相连,组成较大的封包,阻止 大量小封包的发送阻塞网络,从而提高网络应用效率。但是对于时延敏感的应用场景需要关 闭该优化算法。
软中断
RPS 根据数据包的源地址,目的地址以及目的和源端口,计算出一个 hash 值,然后根据这个 hash 值来选择软中断运行的 cpu
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 951488791@qq.com