我们使用 HAProxy 1.6.3 来平衡负载并将 HTTP 流量路由到数百台后端服务器。我们经常重新加载配置(一天几次),既会在服务器发生故障时自动重新加载,也会因管理原因手动重新加载。
问题是,在我们的一台 HAProxy 服务器(Ubuntu 16.04)上运行重新加载命令最多需要 3 分钟。服务器是否有流量似乎并不重要。在我们其他使用相同版本操作系统和 HAProxy 的服务器上,无论负载如何,重新加载都需要 1-5 秒。我们有很多长时间运行的请求,但正如我所说,服务器是否有流量似乎并不重要。
我们可以看到产生了一个新进程,但是它需要几分钟才开始接受流量(或者至少直到新进程的 CPU 使用率攀升至 0% 以上)。
问题是:是什么原因导致 HAProxy 需要这么长时间才能重新加载?它为什么这么长时间没加载?我如何才能找出原因(例如,我需要启用什么级别的日志记录以及我应该在日志中查找什么?)
我们运行以下命令来重新加载:
haproxy -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid -D -sf $(cat /var/run/haproxy.pid)
我们的配置文件如下所示:
global
log 127.0.0.1 local0 notice
maxconn 20000
user haproxy
group haproxy
tune.ssl.default-dh-param 2048
defaults
log global
mode http
option httplog
option dontlognull
option http-keep-alive
option forwardfor
retries 3
option redispatch
timeout connect 5s
timeout check 5s
timeout client 60000
timeout server 60000
stats enable
stats uri /haproxy?stats
stats auth [REDACTED]
option httpchk GET / HTTP/1.0
balance roundrobin
default-server inter 10s fall 2 rise 2
frontend http-in
bind *:80
# Define hosts
acl host_1 hdr(host) -i somehost.somedomain.com
[hundreds of host header configurations]
## switches
use_backend 1 if host_1
[hundreds of if-clauses]
frontend https-in
bind *:443 ssl crt [REDACTED] crt [REDACTED] crt [REDACTED]
# Define hosts
acl host_1 hdr(host) -i somehost.somedomain.com
[hundreds of host header configurations]
## switches
use_backend 1 if host_1
[hundreds of if-clauses]
backend 1
server node1 [some IP] check
server node2 [some IP] check
[lots more backends]
谢谢!
更新:我们发现的唯一区别是慢速服务器使用 Ubuntu 16.04,而快速服务器使用 16.04.1。不确定这是否相关。
更新 2:我们的其他一些服务器也在运行 16.04,并且它们的重新加载速度很快。所以可能不是那样。下一步是重新安装 haproxy,看看是否有帮助。
更新 3:重新安装没有帮助。我们目前正在使用 strace 来尝试找出它在做什么。它似乎正在尝试连接到我们所有的后端,但经常超时。尚不清楚为什么只有这台服务器会超时,以及为什么它拒绝接管,直到所有轮询完成。
答案1
事实证明,新 HAProxy 进程启动缓慢是因为它试图解析所有后端服务器的 DNS。由于我们有很多服务器,而速度慢(或无响应)的 DNS 服务器导致大量查询超时,从而导致进程启动缓慢。
我们更换了更好的 DNS 服务器,现在只需 2 秒。