mengmweng

导航

nio

java:NIO 初次体验高并发带来的快感

在过去的二三年,曾尝试过几次使用nio改写以前的服务器端程序,想体验一下nio + socketchannel带来的快感。

可每次的改写结果都很失败,体会到的全是有失望的感觉,每次的改写经过大量测试后发现并发性能、反应处理速度并没有明显提升,有的时候测试结果还不如 io + socket.

 

最近几天有空,静下心来再次尝试用NIO来改写一个简单的HTTP服务器,先在网上查看了几十篇相关资料,然后根据自已的理解写了一个出来,经过测试感觉处理性能与传统的io+socket+多线程相比基本上差不多,只有在socket并发和内存占用方面比传统的io要表现好一些。

昨天下午,很苦恼,好累。那时我在想,是不是又到了放弃了时候了。

 

今天一觉醒来,精神恢复的不错,又在网上随意的查查nio相关资料,看到一篇文章的开头说了这么一段:
http://zhidao.baidu.com/question/184097099.html

其实不要太迷信nio。这个东西如果你使用不当,效率还不如io高。
而且,使用了nio会造成和以前的代码的不兼容。当然,你是高手,那就例外了。
 

我深有体会,因为我不是java高手,我发现这几年来自已写出来的nio代码,与传说的效率相比差的太远了。

特别是在写 nio + 多线程处理的时候,感觉代码已处于失控状态。

 

后来发现了一篇标题:“基于事件的 NIO 多线程服务器”的文章,网址:http://www.ibm.com/developerworks/cn/java/l-niosvr/

看完以后,发现这篇文章虽然写的时间较早,但是我这几天看到的给我启发最大的一篇资料。

我下载文章下面附带的源代码,看了几遍,我的思路忽然开朗起来。

重新改写之前几天写的代码,经过这一天的努力,写出的代码经过测试,不管是并发性、处理能力方面都有明显的提升。

与以前用传统的io + socket + 多线程写的HTTP服务器对比,用ab测试并发性,nio 处理 2000 并发一点儿问题都没有,反应的速度也相当的快,而传统的io处理方式在处理1000个并发的过程中,客户端ab就崩溃了,NIO与传统的IO测试对比结果:

传统的IO + socket需要几百、上千个线程来处理客户端的请求,而 NIO 只需要几个线程就搞定;

NIO内存占用相比传统的IO降低 80%;

NIO的cpu占用相比传统的IO降低 20%;

NIO处理能力相比传统的IO却提升了 30%;

 

我今天使用NIO写的代码结构相当简单:

1个 Selector 主线程 + 1个 Reader 线程 + 1个 Writer 线程

就能处理几百、上千的并发请求,处理的速度相当的快,内存占用相当的低。

看到测试的结果,我也深刻体会到了nio的一个优点:该read的时候再read,该write时候再write。

不像传统的io,用多个线程处理多个用户的多个连接请求,不管用户提交的数据是否到达,先 read(),没有数据可读的时候,就在那阻塞着。

 

不过话又说回来,传统的io,基于流(Stream),也有它的优点,比如处理流程简单,代码写起来相比nio要简单许多。

 

在这里我还想说一点体会,就是我在网上这几天找相关资料,发现80%的文章介绍的都不够深入,提供的代码基本上都是单线程的,非常适合用来处理短连接,这也一直给我一种错觉,难道NIO不适合处理长连接?

今天找到的这篇:http://www.ibm.com/developerworks/cn/java/l-niosvr/

查看了文章里提供的源代码,使用了三个线程(Selection线程,Reader线程,Write线程),使nio处理长连接成为可能,只需简单修改一下,就OK了

posted on 2013-12-07 15:00  mengmweng  阅读(312)  评论(0编辑  收藏  举报