在调查影响同时受到影响的代理集群的问题时,我发现在建立 SSL 连接时出现了奇怪的行为。
症状是当影响发生时传出的 HTTPS 请求比平时慢,我将其归结为完成 SSL 握手的速度很慢。HTTP 请求/连接不会以同样的方式受到影响。
该问题似乎是由 TCP 3 次握手结束与Client Hello
代理发送之间的延迟在出站连接上引起的。之后,握手正常完成,没有延迟。
以下是流量捕获的一些示例:
到graph.facebook.com
(28.4 秒延迟):
即使在第二个示例中进行了重传,Client Hello
数据包也不应该花费那么长时间才能发出。
一些事实/考虑:
- 该问题在一天中的特定时间(大约 1000 小时和 1700 小时)暂时发生,影响所有主机并在大约 30 分钟后消失。后来,同时
- 这表明存在外部原因(可能是网络),但 tcpdump 输出似乎将责任归咎于本地服务器
- CPU、负载、内存等所有监控的性能指标当时都正常
- 它影响所有 SSL 远程主机
- 随机影响连接,有些行为正常,但许多非常慢
- 吞吐量(握手后)似乎没有受到影响
- 一旦问题通过,与相同远程主机的 SSL 连接始终快速
curl
使用和进行了测试openssl s_client connect
,结果相同
需要说明的是:
- 是什么原因导致本地出现这种延迟?
- Wireshark 会不会骗我?
- 我可以查看哪些其他性能指标/统计信息/命令来进一步解决延迟的原因?
- 是否有任何网络因素(MTU、接收缓冲区、碎片)可以证明这种行为是合理的?
- 我如何找到证据来澄清这是否是我的服务器外部的网络问题?
软件版本:
- 红帽企业 Linux 服务器版本 5.11 (Tikanga)
- OpenSSL 0.9.8e-fips-rhel5 2008 年 7 月 1 日
- 内核 2.6.18-416.el5 #1 SMP 10 月 26 日星期三 12:04:18 EDT 2016 x86_64 x86_64 x86_64 GNU/Linux
编辑:strace信息
按照以下答案的建议做了一些 straces,捕获了这些缓慢的调用:
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()
同一跟踪中的其他此类调用很快。
您可以尝试使用 strace 运行 curl 命令,以查看它们“挂起”的系统调用。我发现这些事情有时与 DNS 查找(或反向 DNS 查找)有关