Netty

image.jpeg

  • Netty 是由 JBOSS 提供的一个 Java 开源框架,现为 Github上的独立项目。
  • Netty 是一个异步的、基于事件驱动的网络应用框架,用以快速开发高性能、高可靠性的网络 IO 程序。
  • Netty主要针对在TCP协议下,面向Clients端的高并发应用,或者Peer-to-Peer场景下的大量数据持续传输的应用。
  • Netty 是目前最流行的 NIO 框架,Netty 在互联网领域、大数据分布式计算领域、游戏行业、通信行业等获得了广泛的应用,知名的 Elasticsearch 、Dubbo 框架内部都采用了 Netty。
  • Netty 可以帮助你快速、简单的开发出一个网络应用,相当于简化和流程化了 NIO 的开发过程

Netty的优点

  • Netty 对 JDK 自带的 NIO 的 API 进行了封装,解决了上述问题。
  • 设计优雅:适用于各种传输类型的统一 API 阻塞和非阻塞 Socket;基于灵活且可扩展的事件模型,可以清晰地分离关注点;高度可定制的线程模型 - 单线程,一个或多个线程池.
  • 使用方便:详细记录的 Javadoc,用户指南和示例;没有其他依赖项,JDK 5(Netty 3.x)或 6(Netty 4.x)就足够了。
  • 高性能、吞吐量更高:延迟更低;减少资源消耗;最小化不必要的内存复制。
  • 安全:完整的 SSL/TLS 和 StartTLS 支持。
  • 社区活跃、不断更新:社区活跃,版本迭代周期短,发现的 Bug 可以被及时修复,同时,更多的新功能会被加入

image.jpeg

为什么要使用Netty


  • 虽然 JAVA NIO 框架提供了 多路复用 IO 的支持,但是并没有提供上层“信息格式” 的良好封装。例如前两者并没有提供针对 Protocol Buffer、JSON 这些信息格式的封装,但是Netty 框架提供了这些数据格式封装(基于责任链模式的编码和解码功能);
  • NIO 的类库和 API 相当复杂,使用它来开发,需要非常熟练地掌握 Selector、ByteBuffer、ServerSocketChannel、SocketChannel 等,需要很多额外的编程技能来辅助使用 NIO,例如,因为 NIO 涉及了 Reactor 线程模型,所以必须必须对多线程和网络编程非常熟悉才能写出高质量的 NIO 程序
  • 要编写一个可靠的、易维护的、高性能的 NIO 服务器应用。除了框架本身要兼容实现各类操作系统的实现外。更重要的是它应该还要处理很多上层特有服务,例如:客户端的权限、还有上面提到的信息格式封装、简单的数据读取,断连重连,半包读写,心跳等等, 这些 Netty 框架都提供了响应的支持。
  • JAVA NIO 框 架 存 在 一 个 poll/epoll bug:Selector doesn’t block on Selector.select(timeout),不能 block 意味着 CPU 的使用率会变成 100%(这是底层 JNI 的问题,上层要处理这个异常实际上也好办)。当然这个 bug 只有在 Linux 内核上才能重现。这个问题在 JDK 1.7 版本中还没有被完全解决,但是 Netty 已经将这个 bug 进行了处理。这个Bug 与操作系统机制有关系的,JDK 虽然仅仅是一个兼容各个操作系统平台的软件,但在 JDK5 和 JDK6 最初的版本中(严格意义上来将,JDK 部分版本都是),这个问题并没有解决,而将这个帽子抛给了操作系统方,这也就是这个 bug 最终一直到 2013 年才最终修复的原因(JDK7 和 JDK8 之间)。

Netty 高性能表现在哪些方面?

  • IO 线程模型:同步非阻塞,用最少的资源做更多的事。
  • 内存零拷贝:尽量减少不必要的内存拷贝,实现了更高效率的传输。
  • 内存池设计:申请的内存可以重用,主要指直接内存。内部实现是用一颗二叉查找树管理内存分配情况。
  • 串形化处理读写:避免使用锁带来的性能开销。即消息的处理尽可能在同一个线程内完成,期间不进行线程切换,这样就避免了多线程竞争和同步锁。表面上看,串行化设计似乎CPU 利用率不高,并发程度不够。但是,通过调整 NIO 线程池的线程参数,可以同时启动多
  • 个串行化的线程并行运行,这种局部无锁化的串行线程设计相比一个队列-多个工作线程模型性能更优。
  • 高性能序列化协议:支持 protobuf 等高性能序列化协议。
  • 高效并发编程的体现:volatile 的大量、正确使用;CAS 和原子类的广泛使用;线程安全 容器的使用;通过读写锁提升并发性能。