花了十多天的时间把原来的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上不存在性能问题。html
而后看到一些资料中提到,jdk7新增的异步IO(AIO)在windows上实现为IOCP,解决了NIO在windows上高并发时遇到的性能问题。linux
在最近三四天,我又重写了代码,此次用AIO重写以前完成的NIO代码花费的时间明显比NIO重写BIO花费的时间短不少,主要缘由是AIO和NIO在处理业务方面的代码有不少类似的地方。windows
使用AIO重写代码后,用ab进行大量的并发测试,测试的结果以下:服务器
• 在没有开启HTTP的持久链接(Connection: close)状况下:网络
用ab进行压力测试,在100-1000并发的状况下,AIO比NIO的并发性能提高了10%左右。并发
• 在开启HTTP的持久链接(Connection: keep-alive)状况下:异步
1. 在50 - 200并发的状况下,AIO比NIO的并发性能慢了20%左右。socket
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。
此时,以前的困扰已渐渐的散去。