在某台新服务器上,发现Nginx启动/重启耗时非常长。相同的配置复制到其他服务器,几乎在瞬间就能完成启动/重启操作,说明新服务器的行为不正常。进一步测试,nginx -t
测试命令耗时也很长。为了不影响Nginx正常使用,需要找到原因解决问题。
Linux系统可以使用strace
命令跟踪进程的系统调用,从而排查可能出问题的位置。由于nginx -t
的耗时也很长,就从这个单次命令看看能不能找出问题关键。
执行命令strace -T nginx -t
,其中-T
参数打印耗时,在进程卡住的地方看到如下输出:
connect(7, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("x.x.x.x")}, 16) = 0 <0.000037> poll([{fd=7, events=POLLOUT}], 1, 0) = 1 ([{fd=7, revents=POLLOUT}]) <0.000029> sendmmsg(7, [{msg_hdr={msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="/223/310/1/0/0/1/0/0/0/0/0/0/4ocsp/10digicert/3com/0/0"..., iov_len=35}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, msg_len=35}, {msg_hdr={msg_name=NULL, msg_namelen=0, msg_iov= [{iov_base="I/320/1/0/0/1/0/0/0/0/0/0/4ocsp/10digicert/3com/0/0"..., iov_len=35}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, msg_len=35}], 2, MSG_NOSIGNAL) = 2 <0.000090> poll([{fd=7, events=POLLIN}], 1, 5000) = 0 (Timeout) <5.005221>
根据行尾输出,poll系统调用耗时5.005221秒,大概率就是问题所在。
那么上面的输出信息能看出什么呢?
首先看connect
这行中的sin_port=htons(53)
,我们知道53是DNS查询端口,说明系统发起了DNS查询;再看第二行sendmmsg
中的iov_base="/223/310/1/0/0/1/0/0/0/0/0/0/4ocsp/10digicert/3com
,携带了证书的OCSP域名,猜测是向DNS服务器发起查询请求;最后的一行poll
有Timeout
提示,表明查询超时,并汇报等待了5.005221秒。
总结上述信息:系统向x.x.x.x发起证书OCSP域名的DNS查询请求,但是DNS超时未响应,导致耗时很长。
终端ping该DNS服务器的IP地址,无法ping通;打开/etc/resolv.conf
,看到该IP地址写在第一行,顺手将其注释掉。
接下来再运行nginx -t
命令,瞬间完成;接着测试启动、重启Nginx,几乎也是瞬间完成,说明问题解决。