这次针对TCP部分对go做了优化,测试结果令人满意。GO单进程(7Gbps)不输c++(8Gbps),是c++使用writev(16Gbps)的一半,GO多进程(59Gbps)完胜c++是c++的好几倍。
备注:之前的测试是在虚拟机上,这次在物理机上,结果可能会略有不同。
Why TCP
TCP是网络通讯的基础,而web则是基于HTTP框架,HTTP又基于TCP。RTMP也是基于TCP。
TCP的吞吐率能达标,那么就奠定了这个语言能开发高性能服务器的基础。
之前srs1.0时,调研过go,写了一个go版本的srs,但是性能和red5差不多就删除了。
现在srs2.0单进程单线程网络吞吐能达到4Gbps(6千客户端,码率522Kbps),GO如果不能达到这个目标,那么SRS就不可能用go重写。
Platform
此次测试在24CPU的服务器上,CPU不是瓶颈。
测试使用lo网卡,直接内存拷贝,网络也不是瓶颈。
CPU和网络都资源充足时,服务器本身的执行速度就是关键了。
OS选用Centos6 64bits。
客户端选用c++做客户端,使用同一个客户端测试。
Write
下面是C++服务器,单进程单线程作为服务器:
g++ tcp.server.cpp -g -O0 -o tcp.server && ./tcp.server 1990 4096
g++ tcp.client.cpp -g -O0 -o tcp.client && ./tcp.client 127.0.0.1 1990 4096
----total-cpu-usage---- -dsk/total- ---net/lo-- ---paging-- ---system--
usr sys idl wai hiq siq| read writ| recv send| in out | int csw
0 6 92 0 0 1| 0 11k|1073M 1073M| 0 0 |2790 81k
0 6 93 0 0 1| 0 7782B|1049M 1049M| 0 0 |2536 76k
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
32573 winlin 20 0 11744 892 756 R 99.9 0.0 17:56.88 ./tcp.server 1990 4096
2880 winlin 20 0 11740 900 764 S 85.3 0.0 0:32.53 ./tcp.client 127.0.0.1 1990 4096
单进程的c++效率还是非常高的1049MBps,对比目前SRS1的168MBps,SRS2跑到的391MBps,其实SRS没有达到性能极限。
下面是go作为服务器,no delay设置为1,即go默认的tcp选项,这个选项会造成tcp性能降低:
go build ./tcp.server.go && ./tcp.server 1 1 1990 4096
g++ tcp.client.cpp -g -O0 -o tcp.client && ./tcp.client 127.0.0.1 1990 4096
----total-cpu-usage---- -dsk/total- ---net/lo-- ---paging-- ---system--
usr sys idl wai hiq siq| read writ| recv send| in out | int csw
0 5 93 0 0 2| 0 7509B| 587M 587M| 0 0 |2544 141k
0 5 93 0 0 2| 0 10k| 524M 524M| 0 0 |2629 123k
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
5496 winlin 20 0 98248 1968 1360 S 100.5 0.0 4:40.54 ./tcp.server 1 1 1990 4096
5517 winlin 20 0 11740 896 764 S 72.3 0.0 3:24.22 ./tcp.client 127.0.0.1 1990 4096
可见在开启tcp no delay的go只有c++的性能的一半。
下面是go作为服务器,关闭了tcp no delay选项,单进程作为服务器:
go build ./tcp.server.go && ./tcp.server 1 0 1990 4096
g++ tcp.client.cpp -g -O0 -o tcp.client && ./tcp.client 127.0.0.1 1990 4096
----total-cpu-usage---- -dsk/total- ---net/lo-- ---paging-- ---system--
usr sys idl wai hiq siq| read writ| recv send| in out | int csw
0 5 93 0 0 1| 0 10k| 868M 868M|