访问 VIP 缓慢的调查

将某个 https 的域名迁移到 lvs,部署完成,绑定 hosts 测试过程中发现 GET 请求非常的缓慢,一个 90KB 的图片耗费的时间长达几十秒甚至超过 1min,这个在未迁移前是从未出现过的现象。
为了一步一步调查,绑定了 hosts 直接访问 rs,结果跟未迁移前效果一样,但是直接访问 VIP 则十分的缓慢。看到这么多的现象,第一反应是难道经过了 VIP 之后 ssl 的处理速度会急剧下降?直接用浏览器自带的开发工具观察好了,发现包含 DNS 查询之前的响应还是很快的,从 Connecting 开始之后的每一步当然包括 SSL 了,其 RT 都是原先的 100 倍以上,Waiting 以及 Receiving 的时间更是长的惊人。
为了方便后续的分析,找了个简单的脚本,可以通过 curl 更方面的观察:

# cat curl-format.txt
    time_namelookup:  %{time_namelookup}\n
       time_connect:  %{time_connect}\n
    time_appconnect:  %{time_appconnect}\n
   time_pretransfer:  %{time_pretransfer}\n
      time_redirect:  %{time_redirect}\n
 time_starttransfer:  %{time_starttransfer}\n
                    ———-\n
         time_total:  %{time_total}\n

curl -w "@curl-format.txt" -o /dev/null -s http://wordpress.com/
连续几次的测试结果跟上面观察的到的一样。当时的第一反应是,虽然怎么都讲不通,经过了 VIP 之后质量还不到原来的 1%,但观察到的结果就是,这个 SSL 把个 VIP 搞的这么慢,为了确认确实是 https 的问题,又找了几个 http 的资源测试了一下,结果,奇怪的事情发生了,也极其的缓慢。
看来最初的判断是错误的,所有的走 VIP 的 GET 都变的极其缓慢了,那为什么之前比这个量大的多的 POST 没有任何异常了?最大的区别就是发送请求 body 的大小了,前者一个静态资源都是几十上百 K,而后者仅仅是返回一个 json 的纯文本。
直接抓包,最初仅仅是在客户端分别抓经过 VIP 跟不经过 VIP 的包,除了每一个 segment 的返回时间差距很大之外,其他的并无差异。后来经我们主管提醒,需要在服务器上也同时抓包,于是一个在原来的 Nginx 上抓,一个在 VIP 上抓,对比相面四张图应该就能看出原因所在了。



上面两张是不走 VIP 的情况,可以看到一个 90K 的文件经过 12 个 TCP segment 就重组了,看 length 这一栏也可以得出,平均一个 segment 都在8K 左右。



上面两张是走 VIP 的,所有的 segment 都变成了 1514(14B 的二层加上 MTU),导致的结果是分了 60 多个 segment。
看到这里立马就联想 2.6.32 ipvs 对 gro 的那个 bug: 2.6.32 – 2.6.36 的内核上在使用 ipvs 的情况下需要关闭 gro。这个我之前曾经单独写过一篇博客。只不过当年没有深入的研究下开启 gro 会有什么具体的影响,这次算是经历过了。
由于配置管理的问题,导致我们一个集群上部分网卡的 gro off 操作没有生效,这个其实是主因。
既然说到 gro/lro,那干脆把 tso, gso 的也一并实践一下。
tso, gso 在 Ubuntu 以及 RedHat 上默认是开启。
gro 在 Ubuntu 上默认关闭,在 Redhat 上默认开启。
lro 的在这两个发行版本上默认均是关闭。

可以看看我下面的两个抓包,第一张是 tso, gso 均关闭的情况

下面一张是单独开启 tso 或者 gso 的情况

现象是不是很明显。所以开启 tso/gso 对于绝大多数的应用来说还是很有必要的,能节约不少资源。

ref:
http://wiki.wireshark.org/CaptureSetup/Offloading

  • 老王

    受教!我搜索了一下,看上去gso是tso的超集,如果是这样的话,我想问一下服务器上是不是只开启gso即可,还是说最好gso,tso都开启

    • http://jaseywang.me/ Jasey Wang

      你看我上面的测试数据,其实只要开任意一个就 ok。
      不同发行版本,同发型版本(distribution)的不同版本(version)的默认值还不大一样。
      我们这边版本型号比较多,但是默认都至少开了一个,所以,并没有什么影响。