据Sun自己说,在JDK7中,异步IO比同步IO性能大约有5%~10%的提升,此外,异步IO模式比同步IO模式更健壮。本来本人对Java的网络的性能就是持怀疑态度的,不管怎么说,怀疑归怀疑,在下结论之前,还是要拿出些证据的,废话不多说,写几片代码,来测试测试JDK7的异步IO和同步IO的性能。到底表现如何?
基本测试环境:
服务器:
CPU AMD5000+
内存 2G
网络 100Mbps
OS Redhat AS5 64bit (此环境运行在虚拟机上)
客户端:
CPU Core P8400
内存 6G
网络 100Mbps
OS Windos XP Pro English 32bit
测试方法:服务器端的接收程序分为异步IO通讯方式和同步IO通讯方式,客户端统一采用多线程异步IO通讯方式向服务器段写一个大小为20,788,639字节的文件,线程开始之前开始计时,客户端所有线程结束后,计结束时间,两个时间点差值计为本次测试文件传输的耗用时间。以10,20,50,100,200,300这6个基准线程测试,每个基准测试4~6次,统计平均时间。
同步网络IO
32K发送缓冲区和接收缓冲区,测试的结果如下:
线程数 | 平均时间 MS | 单个文件消耗时间 MS | 吞吐量 MB/S | 网络利用率 |
20 | 36,273.3 | 1,813.67 | 10.931 | 91.70% |
50 | 92,439.7 | 1,848.79 | 10.724 | 89.96% |
100 | 235,694.7 | 2,356.95 | 8.412 | 70.56% |
同步网络IO,512K发送缓冲区和接收缓冲区,测试的结果如下:
线程数 | 平均时间MS | 单个文件消耗时间 MS | 吞吐量MB/S | 网络利用率 |
10 | 19,480.8 | 1,948.08 | 10.177 | 85.37% |
20 | 36,383.3 | 1,819.16 | 10.898 | 91.42% |
50 | 93,531.3 | 1,870.63 | 10.598 | 88.91% |
100 | 183,011.8 | 1,830.12 | 10.833 | 90.87% |
200 | 568,086.0 | 2,840.43 | 6.980 | 58.55% |
性能比较:虽然测试不是很完全,但是可以看得出,使用512K缓存取得了比较好的性能,之后的分析结果是在发送时读取文件,和接收时写入文件,大的缓存有利于减少文件IO操作。对整个系统性能提高起到了关键的作用。
当线程数达到200个时,客户端出现了丢连接的情况。最少的丢1个,最多的丢16个。
异步IO
32K不完全测试结果
线程数 | 平均时间MS | 单个文件消耗时间 MS | 吞吐量MB/S | 网络利用率 |
100 | 315,328.3 | 3,153.28 | 6.287 | 52.74% |
200 | 783,781.2 | 3,918.91 | 5.059 | 42.44% |
300 | 1,375,141.0 | 4,583.80 | 4.325 | 36.28% |
512K缓存完全测试结果
线程数 | 平均时间MS | 单个文件消耗时间 MS | 吞吐量MB/S | 网络利用率 | ||
10 | 21,023.5 | 2,102.35 | 9.430 | 79.11% | ||
20 | 36,312.8 | 1,815.64 | 10.919 | 91.60% | ||
50 | 94,179.8 | 1,883.60 | 10.525 | 88.29% | ||
100 | 186,320.3 | 1,863.20 | 10.641 | 89.26% | ||
200 | 576,215.0 | 2,881.08 | 6.881 | 57.72% | ||
300 | 883,484.3 | 2,944.95 | 6.732 | 56.47% |
从结果里可以看出,性能最好的表现是在50,100这两个测试点,200后,性能有明显下降。但是,比32K有很大提高,相对于同步的IO,基本上持平,但是在300个线程测试点上,4次测试全部通过,没有出现丢连接的情况。因此,异步IO比同步IO的稳定性要高很多。
所有的测试结果中都显示,100线程后,网络IO出现了明显的下降,事后的分析认为可能是测试的客户端多线程在运行过程中出现了频繁的上下文切换。
本次测试的结论:异步IO比同步IO稳定健壮,性能提高不明显。看来Netty,Mina这些框架要开始考虑使用异步IO咯。
如果你有好的测试网络环境并对这个测试感兴趣,请联系我!