非常低的TCP OpenVPN吞吐量(100Mbit端口,CPU利用率低)

两台服务器之间的OpenVPN传输速率非常慢。 对于这个问题,我会打电话给服务器服务器A和服务器B.

服务器A和服务器B都运行CentOS 6.6。 两者都位于100Mbit线路的数据中心,OpenVPN之外的两台服务器之间的数据传输速度接近〜88Mbps。

但是,当我尝试通过服务器A和服务器B之间build立的OpenVPN连接传输任何文件时,吞吐量正好在6.5Mbps左右。

iperf的testing结果:

[ 4] local 10.0.0.1 port 5001 connected with 10.0.0.2 port 49184 [ 4] 0.0-10.0 sec 7.38 MBytes 6.19 Mbits/sec [ 4] 0.0-10.5 sec 7.75 MBytes 6.21 Mbits/sec [ 5] local 10.0.0.1 port 5001 connected with 10.0.0.2 port 49185 [ 5] 0.0-10.0 sec 7.40 MBytes 6.21 Mbits/sec [ 5] 0.0-10.4 sec 7.75 MBytes 6.26 Mbits/sec 

除了这些OpenVPN iperftesting外,两台服务器都几乎完全处于闲置状态,零负载。

服务器A分配了IP 10.0.0.1,它是OpenVPN服务器。 服务器B分配了IP 10.0.0.2,它是OpenVPN客户端。

服务器A的OpenVPNconfiguration如下:

 port 1194 proto tcp-server dev tun0 ifconfig 10.0.0.1 10.0.0.2 secret static.key comp-lzo verb 3 

服务器B的OpenVPNconfiguration如下:

 port 1194 proto tcp-client dev tun0 remote 204.11.60.69 ifconfig 10.0.0.2 10.0.0.1 secret static.key comp-lzo verb 3 

我注意到了什么:

我的第一个想法是,我瓶颈了服务器上的CPU。 OpenVPN是单线程的,并且这两个服务器都运行不是最快的Intel Xeon L5520处理器。 不过,我在其中一个iperftesting中运行了一个top命令,并按下1来查看内核的CPU利用率,发现每个内核的CPU负载非常低:

 top - 14:32:51 up 13:56, 2 users, load average: 0.22, 0.08, 0.06 Tasks: 257 total, 1 running, 256 sleeping, 0 stopped, 0 zombie Cpu0 : 2.4%us, 1.4%sy, 0.0%ni, 94.8%id, 0.3%wa, 0.0%hi, 1.0%si, 0.0%st Cpu1 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu2 : 0.0%us, 0.0%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.3%st Cpu3 : 0.3%us, 0.0%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu4 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu5 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu6 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu7 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu8 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu9 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu10 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu11 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu12 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu13 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu14 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu15 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 946768k total, 633640k used, 313128k free, 68168k buffers Swap: 4192188k total, 0k used, 4192188k free, 361572k cached 

2.在iperf运行时,Ping时间在OpenVPN隧道上显着增加。 当iperf不运行时,通道上的ping时间一直是60ms(正常)。 但是,当iperf正在运行,并推动交通繁忙时,ping时间变得不稳定。 您可以在下面看到ping时间是如何稳定的,直到第四次ping时才开始iperftesting:

 PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=60.1 ms 64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=60.1 ms 64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=60.2 ms ** iperf test begins ** 64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=146 ms 64 bytes from 10.0.0.2: icmp_seq=5 ttl=64 time=114 ms 64 bytes from 10.0.0.2: icmp_seq=6 ttl=64 time=85.6 ms 64 bytes from 10.0.0.2: icmp_seq=7 ttl=64 time=176 ms 64 bytes from 10.0.0.2: icmp_seq=8 ttl=64 time=204 ms 64 bytes from 10.0.0.2: icmp_seq=9 ttl=64 time=231 ms 64 bytes from 10.0.0.2: icmp_seq=10 ttl=64 time=197 ms 64 bytes from 10.0.0.2: icmp_seq=11 ttl=64 time=233 ms 64 bytes from 10.0.0.2: icmp_seq=12 ttl=64 time=152 ms 64 bytes from 10.0.0.2: icmp_seq=13 ttl=64 time=216 ms 

3.如上所述,我在OpenVPN隧道之外运行了iperf,吞吐量正常,一直保持在〜88Mbps。

我试过了:

1.我认为压缩可能会弄脏事情,所以我通过从两个configuration中删除压缩文件并重新启动OpenVPN来closures压缩。 没有改善。

2.尽pipe我以前发现CPU利用率很低,但我认为默认密码可能有点太密集,系统无法跟上。 所以我cipher RC2-40-CBC到两个configuration(一个非常轻量级的密码),并重新启动OpenVPN。 没有改善。

3.我在各种论坛上看到如何调整片段,mssfix和mtu-tun可能有助于提高性能。 我玩这个文章中描述的一些变化,但再次,没有改善。

什么可能会导致如此糟糕的OpenVPN性能的任何想法?

经过大量的谷歌search和configuration文件的调整,我find了解决办法。 我现在正在获得60Mbps的持续速度并突发到80Mbps。 这比我在VPN之外收到的传输速度要慢一些,但是我认为这样做会很好。

第一步是在服务器和客户端的OpenVPNconfiguration中设置sndbuf 0rcvbuf 0

我在一个公共论坛post (这是一个俄文原文的英文翻译)看到这样的build议后,我做了这个改变,我将在这里引用:

现在是2004年7月,发达国家通常的家庭网速是256-1024 Kbit / s,欠发达国家是56 Kbit / s。 Linux 2.6.7已经在不久之前发布了,并且2.6.8默认情况下将启用TCP Windows Size Scaling的版本仅在一个月内发布。 OpenVPN已经有3年的发展,2.0版几乎已经发布。 其中一个开发人员决定为套接字缓冲区添加一些代码,我认为要统一操作系统之间的缓冲区大小。 在Windows中,如果自定义缓冲区大小已设置,则适配器的MTU会出现问题,因此最终转换为以下代码:

 #ifndef WIN32 o->rcvbuf = 65536; o->sndbuf = 65536; #endif 

如果你使用OpenVPN,你应该知道它可以通过TCP和UDP工作。 如果将自定义TCP套接字缓冲区值设置为64 KB,则TCP窗口大小缩放algorithm无法将窗口大小调整为大于64 KB。 这意味着什么? 这意味着,如果您通过长链接(即美国到俄罗斯)连接到其他VPN站点(ping时间大约为100 ms),则使用默认的OpenVPN缓冲区设置无法获得速度超过5.12 Mbit / s的速度。 您需要至less640 KB缓冲区才能在该链路上获得50 Mbit / s的速率。 UDP会工作得更快,因为它没有窗口大小,但也不会很快。

正如您已经猜到的那样,最新的OpenVPN版本仍然使用64 KB套接字缓冲区大小。 我们应该如何解决这个问题? 最好的办法是禁止OpenVPN设置自定义缓冲区大小。 您应该在服务器和客户端configuration文件中添加以下代码:

 sndbuf 0 rcvbuf 0 

作者继续描述如何将缓冲区大小调整推送到客户端,如果您自己不控制客户端configuration。

在我做出这些改变之后,我的吞吐速率竟然高达20Mbps。 然后我看到单个内核上的CPU利用率有点高,所以我从客户端和服务器上的configuration中删除了comp-lzo (压缩)。 find了! 传输速度高达60Mbps,80Mbps突发。

我希望这可以帮助别人解决OpenVPN慢的问题!

根据configuration的你使用TCP作为隧道的运输。 考虑使用UDP而不是TCP,因为堆叠的TCP连接在数据包丢失情况下会产生问题。

作为参考,看看为什么通过TCP的TCP是一个坏主意