我有一个向 RabbitMQ 发送消息的 API。
我在 HAProxy 后面有一个高可用性 RabbitMQ 集群。
当我对 API 进行加载测试时,我开始看到很多这样的情况:
Recovering from a network failure... Exception in the reader loop: AMQ::Protocol::EmptyResponseError: Empty response received from the server.
在我的独角兽日志中。
如果我通过 haproxy 直接连接到 RabbitMQ,则不会。我哪里做错了,我的 haproxy 配置如下所示:
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
#log loghost local0 info
maxconn 4096
#debug
#quiet
user haproxy
group haproxy
defaults
log global
mode http
retries 3
timeout client 50s
timeout connect 10s
timeout server 50s
option dontlognull
option forwardfor
option httplog
option redispatch
balance roundrobin
# Set up application listeners here.
listen http_frontend
bind *:80
mode http
default_backend http_backend
option httpclose
reqadd X-Forwarded-Proto:\ http
listen https_frontend
bind *:443 ssl crt /etc/haproxy.pem
mode http
default_backend http_backend
reqadd X-Forwarded-Proto:\ https
listen http_bucky_frontend
bind *:1880
mode http
default_backend http_bucky_backend
option httpclose
reqadd X-Forwarded-Proto:\ http
listen https_bucky_frontend
bind *:1443 ssl crt /etc/haproxy.pem
mode http
default_backend http_bucky_backend
reqadd X-Forwarded-Proto:\ https
listen rabbitmq_frontend
bind *:5672
mode tcp
default_backend rabbitmq_backend
option tcplog
listen admin
bind 127.0.0.1:22002
mode http
stats uri /
backend http_backend
mode http
server 0-http_backend x.x.x.x:9000 maxconn 100 check
server 1-http_backend x.x.x.x:9000 maxconn 100 check
backend http_bucky_backend
mode http
option httpchk GET /status
http-check expect string up
server 0-http_bucky_backend x.x.x.x:9000 maxconn 100 check
server 1-http_bucky_backend x.x.x.x:9000 maxconn 100 check
backend rabbitmq_backend
balance roundrobin
mode tcp
server 0-rabbitmq_backend x.x.x.x:5672 maxconn 4000 check
server 1-rabbitmq_backend x.x.x.x:5672 maxconn 4000 check
当负载不足时,负载平衡器通常占用 20-30% 的 CPU
答案1
Nerijus 是对的,此问题是由 HAProxy 客户端超时引起的,这意味着,如果连接空闲超过 X 毫秒,则连接将被断开。
TCP 可以发送保持活动数据包以确保空闲连接保持打开。
您可以使用以下命令检查保持活动数据包的 TCP 参数:
$ cat /proc/sys/net/ipv4/tcp_keepalive_time
默认情况下,此配置等于 7200 秒,这意味着仅当连接空闲超过 2 小时后,TCP 才会开始发送保持活动数据包。
因此,只需将 HAProxy 客户端超时值更新为 > 2 小时,例如:
timeout client 3h
并将 clitcpka 选项添加到您的后端:
backend rabbitmq_backend
balance roundrobin
mode tcp
option clitcpka
server 0-rabbitmq_backend x.x.x.x:5672 maxconn 4000 check
server 1-rabbitmq_backend x.x.x.x:5672 maxconn 4000 check
答案2
从默认部分移除timeout client 50s
并移至除 之外的所有其他部分rabbitmq_frontend
。客户端超时意味着它会关闭 rabbitmq 客户端和 haproxy 之间的 TCP 会话,因此从该套接字读取会得到“”。