Java,Go,NodeJS性能测试

PS: 项目地址:github,这边有所有的代码

写在文章之前:

rpctest文件夹下为测试程序,使用说明见文档,改写自网上淘宝的性能测试用代码

go java nodejs文件夹下为三个不同版本的rpc echo server.

线下测试看,go语言的效率和Nodejs差不多,java因为没有解决并发问题所以只有单线程,效率约为前两者的70~80%,后续将会使用netty进行测试比较

测试环境: Intel i5 4核4线程 内存8G UBuntu x64

文章开始

文章缘由,因为公司中真好有一个代码竞赛,就是比赛写一个rpc服务调用性能竞赛,不能使用现有的轮子,所以java的netty,mina都被毙了,于是就开始了坑跌的
码码。第一个反应肯定使用java,毕竟是最熟悉的语言,然后就开始选型,bio,nio,aio,各种东西都出现了。到底选哪个?因为是追求性能,所以bio第一个被毙了,
然后就是nio和aio了,前者是io复用,后者是epoll,明显后者占优,所以最后锁定了使用aio,然后就开始码码了。

Java Version

首先,肯定是上网找aio的资料,都是不靠谱的,都是抄来抄去,没有什么实质的,除了淘宝邓悟的文章,不过也有缺陷,就是在高压下,会产生pendingwriteException
这个原因就是重复写。如果进行代码调试,将线程数增加,通过我的压测程序就可以发现。如图:

压测时的pendingWriteException

对于这个问题,如果不引入锁概念,就没有办法解决,至少我没解决。但是当时,想到第一个思路就是,使用消息队列的方式对写数据进行缓存,底层使用一个线程进行读取写,确保一个channel只被一个线程写。这样就杜绝了重复写的问题。但是时间紧迫- -,代码没有完善,就提交了。
最后依旧是单线程的程序。不过qps也已经很高了,在100线程,100byte数据的压测下,qps依旧能到50000+.这边就是测试数据:

java压测数据

Go Version

然后就是传说中的Go了,Go有一个很明显的优势,就是协程,不过在这个文件中,我并没有使用到协程。原因就是时间问题,协程的概念就是在线程上做了一个调度,类似于
NodeJs的事件驱动。这边还是使用一个线程一个连接的弱方法,不过因为是直接的2进制文件,运行起来,对服务器的资源消耗依旧是很少。这就是运行时的top截图:

go TOP截图

对比之下,之前的那个Java,在内存占用上确实是一个不小的劣势。

Java TOP截图

而且,在QPS测试上,Go也明显领先于单线程的Java程序,Go的QPS数据如下:

Go压测数据

脱脱的60000+,所以这一关上,Go胜出。

NodeJS Version

最后的永远是主角,传说中性能爆表的NodeJS出现了。这边我用了一个比较作弊的手法,就是建立多个进程进行处理,但是,也只有CPU核数进程,所以在Top上,会看到四个NodeJS
进程,这就是我用来提升性能的一个偏方。所以我们来看这边的压测数据:

NodeJS压测数据

也是脱脱的60000+,不过,top数据就不那么好看了。

NodeJS TOP数据

可见,NodeJS将CPU发挥到了相对极致,不过因为分散,所以整体上还是比较平稳。

总结

其实,总体上看,语言发展至今,语言层面的性能已经相差不大。而且绝大多数的程序还跟本没到语言性能层面。所以,开发的时候,还是要按照项目组最擅长的角度进行技术选型
并不是,新的就是最好的。不过有一点可以透露,NodeJS用了20行代码,Go是50行代码,而Java则是100+,不过我进行编写时所花费的时间是差不多的,所谓的开发效率,则是在相同
熟悉度的情况下。如果一点都不知道NodeJS,而就听说开发效率高就选择了他,到最后,其实得不偿失,不仅效率没有太大的提高,反而导致程序的不稳定。

最后,当然是Go最好了拉。不过。之后我会用netty进行再一度的比较,看看java,到底是不是壮士暮年了。

4 Replies to “Java,Go,NodeJS性能测试”

Leave a Reply

Your email address will not be published. Required fields are marked *