我已经为这个 HAProxy 问题苦苦思索了很长时间,我希望这里有人之前已经遇到过这个问题。
以下是一些信息:
- 我们的 HAP 实例位于三个区域的 AWS 中
- 这些实例接收的唯一流量来自我们的客户
- 我们的每个客户都安装了 HAProxy,将其最终用户的请求分别通过 80 和 443 转发至 1025 和 1026。
- 这些请求通过代理协议通过 TCP 转发到我们的 HAP 实例。
- 然后,我们的 HAP 实例通过 SSL 传输请求并将其转发到端口 80 上的后端。
- 我们的路由都是在 Route53 内部通过健康检查完成的。
- 如果实例未能及时回复,这些健康检查将在 30 秒内进行三次,并将该实例标记为失败。检查每秒进行四次左右。
现在来看看问题:这些服务器时常会挂在 SSL 握手上,导致握手重置(在故障期间在 tcpdump 中发现此问题),从而导致健康检查挂起足够长的时间,导致故障。周末在 6 个实例中发生了约 450 次这种情况。
即使在握手过程中,内存和 CPU 的峰值也不会足以引起任何警报。
以下是 HAP 实例的配置:
# HAProxy Config
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
log 127.0.0.1 local2
pidfile /var/run/haproxy.pid
maxconn 30000
user haproxy
group haproxy
daemon
ssl-default-bind-options no-sslv3 no-tls-tickets
tune.ssl.default-dh-param 2048
# turn on stats unix socket
# stats socket /var/lib/haproxy/stats`
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
option httplog
retries 3
timeout http-request 5s
timeout queue 1m
timeout connect 31s
timeout client 31s
timeout server 31s
maxconn 15000
# Stats
stats enable
stats uri /haproxy?stats
stats realm Strictly\ Private
stats auth $StatsUser:$StatsPass
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend shared_incoming
maxconn 15000
timeout http-request 5s
# Bind ports of incoming traffic
bind *:1025 accept-proxy # http
bind *:1026 accept-proxy ssl crt /path/to/default/ssl/cert.pem ssl crt /path/to/cert/folder/ # https
bind *:1027 # Health checking port
acl gs_texthtml url_reg \/gstext\.html ## allow gs to do meta tag verififcation
acl gs_user_agent hdr_sub(User-Agent) -i globalsign ## allow gs to do meta tag verififcation
# Add headers
http-request set-header $Proxy-Header-Ip %[src]
http-request set-header $Proxy-Header-Proto http if !{ ssl_fc }
http-request set-header $Proxy-Header-Proto https if { ssl_fc }
# Route traffic based on domain
use_backend gs_verify if gs_texthtml or gs_user_agent ## allow gs meta tag verification
use_backend %[req.hdr(host),lower,map_dom(/path/to/map/file.map,unknown_domain)]
# Drop unrecognized traffic
default_backend unknown_domain
#---------------------------------------------------------------------
# Backends
#---------------------------------------------------------------------
backend server0 ## added to allow gs ssl meta tag verification
reqrep ^GET\ /.*\ (HTTP/.*) GET\ /GlobalSignVerification\ \1
server server0_http server0.domain.com:80/GlobalSignVerification/
backend server1
server server1_http server1.domain.net:80
backend server2
server server2_http server2.domain.net:80
backend server3
server server3_http server3.domain.net:80
backend server4
server server4_http server4.domain.net:80
backend server5
server server5_http server5.domain.net:80
backend server6
server server6_http server6.domain.net:80
backend server7
server server7_http server7.domain.net:80
backend server8
server server8_http server8.domain.net:80
backend server9
server server9_http server9.domain.net:80
backend unknown_domain
timeout connect 4s
timeout server 4s
errorfile 503 /etc/haproxy-shared/errors/404.html
答案1
如果涉及 SSL,我会查看您的熵池——也许您已经用尽了它。密切关注“cat /proc/sys/kernel/random/entropy_avail”,看看当您发现问题时它是否下降到 0 左右。
(参考:https://major.io/2007/07/01/check-available-entropy-in-linux/)
如果是这样,您可能需要考虑安装 rngd 来将内核已经执行的操作添加到池中。