<div id="main"><article class="hentry" role="article"><div class="entry-content"> <p>一般我们进行网络测试,主要是测试网络的连通性、网络带宽、网络响应时间等。常用的工具包括ping、traceroute、telnet、ftp等。如测试网络连通性,可以使用ping,traceroute,如果测试防火墙是否配置正确,可以使用telnet和traceroute -p,使用ping命令可以测试网络延迟,ftp则用来测试网络带宽。</p>
<p>但如果需要做一些更为深入的测试,如测试不同包大小的不同类型的业务的网络处理能力,则需要更专业的工具,如netperf,iperf等。</p>
<h2 id="netperf">netperf测试工具介绍</h2>
<p><a href="http://www.netperf.org/">netperf</a>是一个开源的网络性能测试工具。可以在AIX和LINUX平台上安装,支持跨平台使用。</p>
<p>netperf可以进行的测试TCP网络性能、UDP网络性能,并且可以模拟Client/Server长连接或短连接场景,因此能更接近实际网络的使用环境进行测试和评估。</p>
<h2 id="section">安装</h2>
<p>从<a href="http://www.netperf.org/">官方网站</a>可以下载源代码进行编译安装。安装过程基本上是老三步,即</p>
<pre><code>./configcure make make install </code></pre>
<p>默认安装路径是/usr/local下的各目录。在AIX等系统中,可能需要自己设置PATH环境变量,或使用–prefix参数更改安装路径。</p>
<p>对于<em>SUSE</em>,在安装中发现,在内核版本为2.6.16(SUSE 10)时,会出现编译错误:</p>
<pre><code>nettest_omni.o: In function `recv_data_no_copy': nettest_omni.c:(.text+0x6e44): undefined reference to `splice' nettest_omni.c:(.text+0x6e7b): undefined reference to `splice' collect2: ld returned 1 exit status make[3]: *** [netperf] Error 1 make[3]: Leaving directory `/root/py/netperf-2.6.0/src' make[2]: *** [all-recursive] Error 1 make[2]: Leaving directory `/root/py/netperf-2.6.0/src' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/root/py/netperf-2.6.0' </code></pre>
<p>经查,splice系统调用是在2.6.17内核版本以后出现的,因此换用SUSE 11编译通过。</p>
<p>如果是UBUNTU之类的版本,因为软件库中已经有了netperf,可以用包管理器安装。比如UBUNTU中使用:</p>
<pre><code>sudo apt-get install netperf </code></pre>
<h2 id="section-1">使用</h2>
<h3 id="section-2">启动服务</h3>
<p>netperf包括两个程序。一个是客户端netperf,用于模拟各类网络行为。另一个为服务器程序netserver。用于接收客户端的请求。启动服务的操作类似于:</p>
<pre><code># netserver Starting netserver with host 'IN(6)ADDR_ANY' port '12865' and family AF_UNSPEC </code></pre>
<p>默认情况下TCP服务的监听启动在12865端口上。可以通过-p参数修改。</p>
<p>未发现使用了哪个UDP端口,估计是在测试时根据netperf启用的测试项目再启用端口的。</p>
<h3 id="netperf-1">netperf参数说明</h3>
<p>netperf的参数格式如下:</p>
<pre><code>netperf [global options] -- [test options] </code></pre>
<p>其中,global options为通用参数,所有测试项目都涉及或是公共的参数,常用的有:</p>
<p>-H 主机名或IP 指定运行netserver的服务器的IP</p>
<p>-l 测试时长 指定测试的时间长度,单位为秒</p>
<p>-t 测试项目 指定测试的内容。测试项目如下:</p>
<p>TCP批量数据传输测试 TCP_STREAM</p>
<pre><code> TCP_SENDFILE TCP_MAERTS </code></pre>
<p>TCP请求应答(长连接)模式测试 TCP_RR</p>
<pre><code> TCP_CRR </code></pre>
<p>UCP批量数据传输测试 UDP_STREAM</p>
<pre><code> UDP_RR DLCO_STREAM DLCO_RR DLCL_STREAM DLCL_RR STREAM_STREAM STREAM_RR DG_STREAM DG_RR SCTP_STREAM SCTP_STREAM_MANY SCTP_RR SCTP_RR_MANY LOC_CPU REM_CPU </code></pre>
<p>test specific options是测试项用的参数,它与全局参数之间要用“–”分开类似</p>
<pre><code>netperf -H 127.0.0.1 -l 30 -- -m 2048 </code></pre>
<p>测试项参数与测试项目相关。</p>
<h2 id="section-3">常用测试项目</h2>
<h3 id="section-4">网络带宽测试</h3>
<p>带宽测试一般使用-t TCP_STREAM测试项,这也是netperf的默认测试项目。此项测试与ftp类似可以测试系统的带宽,但可以通过参数进行更多的设置。比如:</p>
<pre><code>$ netperf -H 127.0.0.1 -l 60 MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 127.0.0.1 () port 0 AF_INET : demo Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. 10^6bits/sec 87380 16384 16384 60.00 2760.70 </code></pre>
<p>第一列为服务端接收包的Socket缓冲区大小,这里没87380</p>
<p>第二列为客户端发送数据的Socket缓冲区大小,这里为16384</p>
<p>第三列为发送的消息的大小,这里为16384</p>
<p>第四列为测试时长</p>
<p>第五列为测试的速率,单位为M,这里结果为2.7G。因为使用的是localhost,实际是在本机的内存中收发的数据。</p>
<p>TCP_STREAM的常用测试参数有:</p>
<p>-s 缓冲区大小 指定客户端发送数据的缓冲区大小 -S 缓冲区大小 指定服务端接收数据的缓冲区大小</p>
<p>-m 发送消息大小 单位为bytes</p>
<p>-M 接收消息大小 单位为bytes</p>
<p>可以调整这些参数,了解哪些因素对传输速率有影响。比如将发送缓冲变大,测试结果变化不大:</p>
<div class="bogus-wrapper"><notextile><figure class="code"><div class="highlight"><table><tr> <td class="gutter"><pre class="line-numbers"><span class="line-number">1</span> <span class="line-number">2</span> <span class="line-number">3</span> <span class="line-number">4</span> <span class="line-number">5</span> <span class="line-number">6</span> <span class="line-number">7</span> <span class="line-number">8</span> </pre></td> <td class="code"><pre><code class=""><span class="line">$ netperf -H 127.0.0.1 -l 60 -- -s 65535 </span><span class="line">MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 127.0.0.1 () port 0 AF_INET : demo </span><span class="line">Recv Send Send </span><span class="line">Socket Socket Message Elapsed </span><span class="line">Size Size Size Time Throughput </span><span class="line">bytes bytes bytes secs. 10^6bits/sec </span><span class="line"> </span><span class="line"> 87380 131070 131070 60.00 2672.42 </span></code></pre></td> </tr></table></div></figure></notextile></div>
<p>而改变接收缓冲和发包大小,则可以提升性能:</p>
<pre><code>$ netperf -H 127.0.0.1 -l 60 -- -S 65535 MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 127.0.0.1 () port 0 AF_INET : demo Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. 10^6bits/sec 131070 16384 16384 60.00 3058.22 $ netperf -H 127.0.0.1 -l 60 -- -m 65535 MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 127.0.0.1 () port 0 AF_INET : demo Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. 10^6bits/sec 87380 16384 65535 60.00 3266.55 </code></pre>
<h3 id="udp">UDP协议的传输性能</h3>
<p>与网络带宽测试类似,只是更换了协议,所以这个项目是UDP_STREAM:</p>
<pre><code>$ netperf -H 127.0.0.1 -l 60 -t UDP_STREAM MIGRATED UDP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 127.0.0.1 () port 0 AF_INET : demo Socket Message Elapsed Messages Size Size Time Okay Errors Throughput bytes bytes secs # # 10^6bits/sec 212992 65507 60.00 440506 0 3847.46 212992 60.00 433151 3783.22 </code></pre>
<p>与TCP_STREAM不太一样,测试结果中有两行数据。第一行是客户端的,第二行是服务端。</p>
<p>第一列为缓冲区大小,在netperf测试中,两端的缓冲区大小会设置成一样大。</p>
<p>第二列为消息大小</p>
<p>第三列为测试传输时间</p>
<p>第四列为传输数据包量,UDP由于协议不保证传输可靠性,收发消息数量不一样多,而且实际生产环境收包量可能比发包少得更多。从数据看,这个包数量应是每秒数量(消息大小和速度的单位不一样)</p>
<p>最后是测试的速率,可以看到要比TCP协议快一些。这是协议决定的。</p>
<h3 id="tcp">TCP长连接请求应答模式测试</h3>
<p>除了网络数据传输,大量的网络流量是请求/应答式的,即一方发送一个报文,另一方回复一个。而且通常这类请求和回复的报文大小不一样大,甚至差别很大。netperf可以简单模拟这类应用场景,进行网络性能测试。测试使用类型为TCP_RR。</p>
<p>最简单的TCP_RR测试如下:</p>
<pre><code>$ netperf -H 127.0.0.1 -l 60 -t TCP_RR MIGRATED TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 127.0.0.1 () port 0 AF_INET : demo : first burst 0 Local /Remote Socket Size Request Resp. Elapsed Trans. Send Recv Size Size Time Rate bytes Bytes bytes bytes secs. per sec 16384 87380 1 1 60.00 13517.65 16384 87380 </code></pre>
<p>测试结果分为两行,第一行是本地,第二行是远端(服务端)</p>
<p>第一列和第二列应该还是缓冲区,只是和STREAM测试的顺序相反。</p>
<p>第三、四列为请求和返回包的大小。默认为1位。</p>
<p>第五列为测试时间</p>
<p>第六列为交易速率,这次是笔数/每秒,不再是带宽。</p>
<p>默认的包大小实际业务中不可能发生,可以通过参数进行调整,来模拟真实的情况。使用测试参数-r 请求包大小,应答包大小(-r request,response)来测试。注意此参数单位为BYTES,实际的业务一般是以字节为单位的报文:</p>
<pre><code>$ netperf -H 127.0.0.1 -l 60 -t TCP_RR -- -r 64,2048 MIGRATED TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 127.0.0.1 () port 0 AF_INET : demo : first burst 0 Local /Remote Socket Size Request Resp. Elapsed Trans. Send Recv Size Size Time Rate bytes Bytes bytes bytes secs. per sec 16384 87380 64 2048 60.00 13129.09 16384 87380 </code></pre>
<p>此测试使用8字节的请求,256字节的返应答包进行测试,测试结果相对默认值轻微下降。</p>
<h3 id="tcp-1">TCP短连接请求应答模式测试</h3>
<p>TCP请求的另一大类是类似HTTP业务的短连接请求应答报文。对应的测试项是TCP_CRR:</p>
<pre><code>$ netperf -H 127.0.0.1 -l 60 -t TCP_CRR MIGRATED TCP Connect/Request/Response TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 127.0.0.1 () port 0 AF_INET : demo Local /Remote Socket Size Request Resp. Elapsed Trans. Send Recv Size Size Time Rate bytes Bytes bytes bytes secs. per sec 16384 87380 1 1 60.00 2210.55 16384 87380 </code></pre>
<p>测试参数和显示与TCP_RR类似。由于业务类型的影响,速率降得比厉害。</p>
<h3 id="udp-1">UDP连接请求应答模式测试</h3>
<p>由于UDP协议的原因,UDP请求应答不分长短连接。只有UDP_RR一个测试项目,测试参数也类似TCP类的测试:</p>
<pre><code>$ netperf -H 127.0.0.1 -l 60 -t UDP_RR MIGRATED UDP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 127.0.0.1 () port 0 AF_INET : demo : first burst 0 Local /Remote Socket Size Request Resp. Elapsed Trans. Send Recv Size Size Time Rate bytes Bytes bytes bytes secs. per sec 212992 212992 1 1 60.00 15837.63 212992 212992 </code></pre>
<p>理论上,UDP的测试结果要好于TCP,但在实际网络中,可能受网络设备配置等影响,存在一定未知数。</p>
<h2 id="section-5">如何进行模拟测试</h2>
<p>首先需要搞好测试用例。要明确业务的类型,协议,好确定选择哪个测试项目,要了解业务的特性,如一般包的大小等信息,以便选择合适的参数。这些参数可以根据业务设计来确定,也可能需要通过业务监控数据来获取。例如通过监控数据中的最大流量和最大IO量,可以大致评估一下数据包的大小,当然这种评估很不精确。</p>
<p>由于决定网络性能的因素有一部分和配置相关,因此在测试中可以变更缓冲区大小等参数,以便了解是否需要对网络参数进行调整。</p>
<p class="post-footer"> 原文链接地址: <a href="http://pangyi.github.io/blog/20141210/wang-luo-ce-shi-gong-ju-netperf/">http://pangyi.github.io/blog/20141210/wang-luo-ce-shi-gong-ju-netperf/</a><br> written by <a href="http://pangyi.github.io">PangYi</a> posted at <a href="http://pangyi.github.io">http://pangyi.github.io</a> </p> </div></article></div>