《Netty 权威指南》—— 选择Netty的理由

声明:本文是《Netty 权威指南》的样章,感谢博文视点授权并发编程网站发布样章,禁止以任何形式转载此文。

在开始本节之前,我先讲一个亲身经历的故事:曾经有两个项目组同时用到了NIO编程技术,一个项目组选择自己开发NIO服务端,直接使用JDK原生的API,结果2个多月过去了,他们的NIO服务端始终无法稳定,问题频出。由于NIO通信是它们的核心组件之一,因此,项目的进度受到了严重的影响,领导对此非常恼火。另一个项目组直接使用Netty作为NIO服务端,业务的定制开发工作量非常小,测试表明,功能和性能都完全达标,项目组几乎没有在NIO服务端上花费额外的时间和精力,项目进展也非常顺利。

这两个项目组的不同遭遇提醒我们:开发出高质量的NIO程序并不是一件简单的事情,除去NIO固有的复杂性和BUG不谈,作为一个NIO服务端需要能够处理网络的闪断、客户端的重复接入、客户端的安全认证、消息的编解码、半包读写等等,如果你没有足够的NIO编程经验积累,一个NIO框架的稳定往往需要半年甚至更长的时间。更为糟糕的是一旦在生产环境中发生问题,往往会导致跨节点的服务调用中断,严重的可能会导致整个集群环境都不可用,需要重启服务器,这种非正常停机会带来巨大的损失。

从可维护性角度看,由于NIO采用了异步非阻塞编程模型,而且是一个IO线程处理多条链路,它的调试和跟踪非常麻烦,特别是生产环境中的问题,我们无法有效调试和跟踪,往往只能靠一些日志来辅助分析,定位难度很大。

2.6.1.不选择JAVA原生NIO编程的原因

在本小节,我们总结下为什么不建议开发者直接使用JDK的NIO类库进行开发的原因:

1)      NIO的类库和API繁杂,使用麻烦,你需要熟练掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等;

2)      需要具备其它的额外技能做铺垫,例如熟悉Java多线程编程,因为NIO编程涉及到Reactor模式,你必须对多线程和网路编程非常熟悉,才能编写出高质量的NIO程序;

3)      可靠性能力补齐,工作量和难度都非常大。例如客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常码流的处理等等,NIO编程的特点是功能开发相对容易,但是可靠性能力补齐工作量和难度都非常大;

4)      JDK NIO的BUG,例如臭名昭著的epoll bug,它会导致Selector空轮询,最终导致CPU 100%。官方声称在JDK1.6版本的update18修复了该问题,但是直到JDK1.7版本该问题仍旧存在,只不过该bug发生概率降低了一些而已,它并没有被根本解决。该BUG以及与该BUG相关的问题单如下:

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6403933

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=2147719

异常堆栈如下:

01 java.lang.Thread.State: RUNNABLE
02         at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
03         at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210)
04         at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
05         at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
06         - locked <0x0000000750928190> (a sun.nio.ch.Util$2)
07         - locked <0x00000007509281a8> (a java.util.Collections$UnmodifiableSet)
08         - locked <0x0000000750946098> (a sun.nio.ch.EPollSelectorImpl)
09         at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
10         at net.spy.memcached.MemcachedConnection.handleIO(MemcachedConnection.java:217)
11         at net.spy.memcached.MemcachedConnection.run(MemcachedConnection.java:836)

由于上述原因,在大多数场景下,我不建议大家直接使用JDK的NIO类库,除非你精通NIO编程或者有特殊的需求,在绝大多数的业务场景中,我们可以使用NIO框架Netty来进行NIO编程,它既可以作为客户端也可以作为服务端,同时支持UDP和异步文件传输,功能非常强大。

下个小节我们就看看为什么选择Netty作为基础通信框架。

2.6.2.为什么选择Netty

Netty是业界最流行的NIO框架之一,它的健壮性、功能、性能、可定制性和可扩展性在同类框架中都是首屈一指的,它已经得到成百上千的商用项目验证,例如Hadoop的RPC框架avro使用Netty作为底层通信框架。很多其它业界主流的RPC框架,也使用Netty来构建高性能的异步通信能力。

通过对Netty的分析,我们将它的优点总结如下:

1)      API使用简单,开发门槛低;

2)      功能强大,预置了多种编解码功能,支持多种主流协议;

3)      定制能力强,可以通过ChannelHandler对通信框架进行灵活的扩展;

4)      性能高,通过与其它业界主流的NIO框架对比,Netty的综合性能最优;

5)      成熟、稳定,Netty修复了已经发现的所有JDK NIO BUG,业务开发人员不需要再为NIO的BUG而烦恼;

6)      社区活跃,版本迭代周期短,发现的BUG可以被及时修复,同时,更多的新功能会被加入;

7)      经历了大规模的商业应用考验,质量已经得到验证。在互联网、大数据、网络游戏、企业应用、电信软件等众多行业得到成功商用,证明了它可以完全满足不同行业的商业应用。

正是因为这些优点,Netty逐渐成为Java NIO编程的首选框架。

2.7 .总结

本章通过一个简单的demo开发-时间服务器程序,让大家熟悉传统的同步阻塞IO、伪异步IO、非阻塞IO(NIO)和异步IO(AIO)的编程和使用差异。然后对比了各自的优缺点,给出了使用建议。

最后,我们详细介绍了为什么不建议读者朋友们直接使用JDK的NIO原生类库进行异步IO的开发,同时对Netty的优点进行分析和总结,给出使用Netty进行NIO开发的理由。

相信学完本章之后,大家对Java的网络编程已经有了初步的认识,从下一个章节开始,我们正式进入Netty的世界,学习和掌握基于Netty的网络开发。 

时间: 2024-09-19 09:08:55

《Netty 权威指南》—— 选择Netty的理由的相关文章

《Netty 权威指南》—— 4种IO的对比

声明:本文是<Netty 权威指南>的样章,感谢博文视点授权并发编程网站发布样章,禁止以任何形式转载此文. 2.5.1.概念澄清 为了防止由于对一些技术概念和术语的理解或者叫法不一致引起歧义,本小节特意对本书中的专业术语或者技术用语做下声明,如果它们与其它的一些技术书籍术语不一致,请以本小节的解释为准. 2.5.1.1. 异步非阻塞IO 很多人喜欢将JDK1.4提供的NIO框架称为异步非阻塞IO,但是,如果严格按照Unix网络编程模型和JDK的实现进行区分,实际上它只能被称为非阻塞IO,不能叫

《Netty权威指南》目录

<Netty权威指南>是全球第二本.中国第一本Netty教材,它由华为平台中间件资深架构设计师李林锋撰写,作者有6年多的NIO设计和开发实战经验,多次受邀进行Netty和 NIO编程培训. 本书基于最新的Netty5.0 版本撰写,从Netty开发环境的搭建,到第一个基于Netty的NIO服务端和客户端程序的开发,一步步的让读者从入门到精通,熟练的掌握基于Netty 的NIO开发,理解Netty的架构设计原理,可以对Netty进行深度的定制设计和开发. 本书共分为五部分:第一部分介绍 JAVA

《Netty 权威指南》样章

声明:本文是<Netty 权威指南>的样章目录,感谢博文视点授权并发编程网站发布样章,禁止以任何形式转载此文. 第 2 章  NIO入门 在本章节,我们分别对JDK的BIO.NIO和JDK1.7最新提供的NIO2.0的使用进行详细说明,通过流程图和代码讲解,让大家体会到随着Java IO类库的不断发展和改进,基于Java的网络编程会变得越来越简单,随着异步IO功能的增强,基于Java NIO开发的网络服务器甚至不逊色于采用C++开发的网络程序. 本章主要内容包括:  传统的同步阻塞式IO编程

《Netty 权威指南》—— NIO类库简介

声明:本文是<Netty 权威指南>的样章,感谢博文视点授权并发编程网站发布样章,禁止以任何形式转载此文. 在介绍NIO编程之前,我们首先需要澄清一个概念,NIO到底是什么的简称?有人称之为New IO,因为它相对于之前的IO类库是新增的,所以被称为New IO,这是它的官方叫法.但是,由于之前老的IO类库是阻塞IO,New IO类库的目标就是要让JAVA支持非阻塞IO,所以,更多的人喜欢称之为非阻塞IO(Non-block IO),由于非阻塞IO更能够体现NIO的特点,所以本书使用的NIO都

《Netty 权威指南》—— NIO创建的TimeClient源码分析

声明:本文是<Netty 权威指南>的样章,感谢博文视点授权并发编程网站发布样章,禁止以任何形式转载此文. 我们首先还是看下如何对TimeClient进行改造: public class TimeClient { /** * @param args */ public static void main(String[] args) { int port = 8080; if (args != null && args.length > 0) { try { port =

《Netty 权威指南》—— 服务端序列图

声明:本文是<Netty 权威指南>的样章,感谢博文视点授权并发编程网站发布样章,禁止以任何形式转载此文. 下面,我们对NIO服务端的主要创建过程进行讲解和说明,作为NIO的基础入门,我们将忽略掉一些在生产环境中部署所需要的一些特性和功能. 步骤一:打开ServerSocketChannel,用于监听客户端的连接,它是所有客户端连接的父管道,代码示例如下: 1 ServerSocketChannel acceptorSvr = ServerSocketChannel.open(); 步骤二:绑

《Netty 权威指南》—— 传统的BIO编程

声明:本文是<Netty 权威指南>的样章,感谢博文视点授权并发编程网站发布样章,禁止以任何形式转载此文. 网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接请求,通过三次握手建立连接,如果连接建立成功,双方就可以通过网络套接字(Socket)进行通信. 在基于传统同步阻塞模型开发中,ServerSocket负责绑定IP地址,启动监听端口,Socket负责发起连接操

《Netty 权威指南》—— NIO客户端序列图

声明:本文是<Netty 权威指南>的样章,感谢博文视点授权并发编程网站发布样章,禁止以任何形式转载此文. 步骤一:打开SocketChannel,绑定客户端本地地址(可选,默认系统会随机分配一个可用的本地地址),示例代码如下: 1 SocketChannel clientChannel = SocketChannel.open(); 步骤二:设置SocketChannel为非阻塞模式,同时设置客户端连接的TCP参数,示例代码如下: 1 clientChannel.configureBlock

《Netty 权威指南》—— AIO 创建的TimeServer源码分析

声明:本文是<Netty 权威指南>的样章,感谢博文视点授权并发编程网站发布样章,禁止以任何形式转载此文. NIO2.0引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现.异步通道提供两种方式获取获取操作结果: 通过java.util.concurrent.Future类来表示异步操作的结果: 在执行异步操作的时候传入一个java.nio.channels. CompletionHandler接口的实现类作为操作完成的回调. NIO2.0的异步套接字通道是真正的异步非阻塞IO