摘自:http://blog.csdn.net/u010154380/article/details/64443762java
《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等;app
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.Util2)
07
- locked <0x00000007509281a8> (a java.util.Collections2) 07 - locked <0x00000007509281a8> (a java.util.CollectionsUnmodifiableSet)
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的网络开发。