浅谈使用NIO,AIO的感受

花了十多天的时间把原来的WEB服务由BIO(阻塞IO)模式改写成NIO(非阻塞IO)模式,然后在xp机子上用ab测试并发性能,确实提升了30%左右的并发性能,测试完成后,当时感觉还是挺满意的。几天前在网上看到有文章中谈到关于NIO中的select()在windows机子上的实现有性能问题,原因是NIO在windows上使用的是select/poll技术(网上有文章指出:select ()最不能忍受的是一个进程所打开的FD是有一定限制的,由FD_SETSIZE设置,默认值是2048。对于那些需要支持几千上万连接服务器来说显然太少了。传统的select/poll另一个致命弱点就是当你拥有一个很大的socket集合,不过由于网络延时,任一时间只有部分的socket是"活跃"的,但是select/poll每次调用都会线性扫描全部的集合,导致效率呈现线性下降。但是epoll不存在这个问题。),但在linux2.6+上,Java的NIO实现为epoll,所以在linux上不存在性能问题。

然后看到一些资料中提到,jdk7新增的异步IO(AIO)在windows上实现为IOCP,解决了NIO在windows上高并发时遇到的性能问题。

在最近三四天,我又重写了代码,这次用AIO重写之前完成的NIO代码花费的时间明显比NIO重写BIO花费的时间短很多,主要原因是AIO和NIO在处理业务方面的代码有很多相似的地方。

使用AIO重写代码后,用ab进行大量的并发测试,测试的结果如下:

• 在没有开启HTTP的持久连接(Connection: close)情况下:

用ab进行压力测试,在100-1000并发的情况下,AIO比NIO的并发性能提升了10%左右。

• 在开启HTTP的持久连接(Connection: keep-alive)情况下:

1. 在50 - 200并发的情况下,AIO比NIO的并发性能慢了20%左右。

2. 在200 - 500并发的情况下,AIO比NIO的并发性能慢了10% - 5%左右。

3. 在500 - 1000并发的情况下,AIO与NIO并发性能基本持平,有的时候还表现更快一些。

我的xp机子上,ab最大只能开到1000,1000+的情况,我没测试。

原以为使用AIO重写的代码在各个方面都会强于NIO,曾经因为这个测试结果困扰了我一二天时间。

今天上午在CSDN上看到一篇性能调优攻略:http://sd.csdn.net/a/20120621/2806814_2.html,其中有一段内容提到异步IO:

异步操作。我们知道Unix下的文件操作是有block和non-block的方式的,像有些系统调用也是block式的,如:Socket下的select,Windows下的WaitforObject之类的,如果我们的程序是同步操作,那么会非常影响性能,我们可以改成异步的,但是改成异步的方式会让你的程序变复杂。异步方式一般要通过队列,要注间队列的性能问题,另外,异步下的状态通知通常是个问题,比如消息事件通知方式,有callback方式,等,这些方式同样可能会影响你的性能。但是通常来说,异步操作会让性能的吞吐率有很大提升(Throughput),但是会牺牲系统的响应时间(latency)。这需要业务上支持。

通过AIO重写的代码可以看出,AIO的每一次callback(回调)是通过线程池中的一个线程执行的,而我之前写的NIO代码仅在一个线程中执行(仅使用一个selector),可能因此在开启持久连接时,低并发的情况下会出现AIO的并发性能还不如NIO,当并发数越来越高的时候,测试结果也表明,AIO的并发性能开始慢慢接近甚至超越NIO。

此时,之前的困扰已渐渐的散去。 

2012-06-25

原文地址:https://www.cnblogs.com/personnel/p/4583279.html