Linux:由于延迟的客户端问候,SSL握手很慢

在调查一个影响同时受到影响的代理集群的问题时,我发现在build立SSL连接时存在奇怪的行为。

现象的症状是,当出现冲击时,传出的HTTPS请求比平常要慢,我已经把它放慢了,以便完成SSL握手。 HTTP请求/连接不会以相同的方式受到影响。

这个问题似乎是由于TCP三次握手结束和代理发送Client Hello之间的延迟而导致的出站连接。 之后,握手正常完成,没有延迟。

以下是来自stream量捕获的一些示例:

to api.twitter.com (延迟2.4秒): api.twitter.com

graph.facebook.com (延迟28.4秒): graph.facebook.com

即使在第二个例子中重传, Client Hello包也不应该花那么长时间才能出去。

一些事实/考虑:

  • 这个问题在一天中的特定时间(大约1000小时和1700小时)暂时出现,影响所有主机并在30分钟内消失。 以后,同时
  • 这将表明一个外部原因(networking,也许),但tcpdump输出似乎把责任放在本地服务器
  • CPU,负载,内存和其他所有监视的性能指标都是正常的
  • 它会影响所有的SSL远程主机
  • 影响连接随机,一些行为正常,但很多是非常缓慢的
  • 吞吐量(握手后)似乎没有受到影响
  • 一旦问题通过,SSL连接到相同的远程主机一直很快
  • testing用curlopenssl s_client connect ,结果相同

需要澄清的是:

  1. 这可能是什么原因造成了这样的拖延?
  2. Wirehark可以欺骗我吗?
  3. 还有什么其他的性能指标/统计/命令可以用来进一步排查延误的原因?
  4. 是否有任何networking因素(MTU,接收缓冲区,碎片),可以certificate这种行为?
  5. 我如何find证据来澄清是否是我的服务器外部的networking问题?

软件版本

  • 红帽企业Linux服务器版本5.11(Tikanga)
  • OpenSSL 0.9.8e-fips-rhel5 2008年7月1日
  • kernel 2.6.18-416.el5#1 SMP Wed Oct 26 12:04:18 EDT 2016 x86_64 x86_64 x86_64 GNU / Linux

编辑:strace信息

根据下面的答案推荐了几条路线,发现了这些缓慢的呼叫:

 strace -T -o output.strace openssl s_client -connect 104.244.42.66:443 </dev/null connect(3, {sa_family=AF_INET, sin_port=htons(443), sin_addr=inet_addr("104.244.42.66")}, 16) = 0 <2.266597> poll([{fd=4, events=POLLIN}], 1, 5000) = 1 ([{fd=4, revents=POLLIN}]) <2.387366> write(3, "\26\3\1\0S\1\0\0O\3\1X\342\24\3556c\354\270T\302\225[\236\317\327\305\205r\177\t/"..., 88) = 88 <0.000034> read(3, "\26\3\1\0001\2\0", 7) = 7 <2.556229> read(3, "\0-\3\1\332\37\254+\240\320\236qA\375\275L\23l\340\355\205x\264\274\273\213\377\323&\345\307O"..., 47) = 47 <0.000011> read(3, "\26\3\1\v\273", 5) = 5 <0.000007> (...) read(3, "\24\3\1\0\1", 5) = 5 <2.223115> 

poll()调用是一个反向DNS查询,它是这样做的:

 sendto(4, "\3623\1\0\0\1\0\0\0\0\0\0\00266\00242\003244\003104\7in-ad"..., 44, MSG_NOSIGNAL, NULL, 0) = 44 <0.000157> 

其他这样的poll()调用在同一个trace中是很快的。

你可以试着用strace来运行你的curl命令,看看他们挂起了哪个系统调用。 我发现这些东西有时与DNS查找(或反向DNS查找)相关,

 strace curl https://[...]