HAProxy Keep-Alive 未按预期工作
HAProxy Keep-Alive not working as expected
我对 HTTP Keep-Alive 的推理是否正确?这是我的假设:
- 在现代浏览器中,持久连接是默认设置,因此 连接:Keep-Alive 响应 header 不太可能由 HAProxy 发送那些客户。 不看到它并不一定意味着连接不持久。
- A Keep-Alive 意味着很短的持续时间,例如几百毫秒,在此期间客户端可以重复使用与同一服务器的相同连接(用于下载图像等用途,CSS 和 JavaScript 在同一页上)
- 可以通过 cookie 或 stick tables 实现更长的持久性
我问的原因是因为当我设置长 keep-alive 超时(通过 timeout http-keep-alive
)时,键入 F5 会以同样快的速度快速加载不同的后端服务器,在所有三个服务器之间轮换而没有任何效果来自 keep-alive。我本以为如果我在 keep-alive 5 秒超时期间按 F5,我仍然会得到相同的后端服务器。
我是不是想错了?
这是我的 HAproxy 配置,我将 keep-alive 超时设置为 5 秒:
defaults
timeout connect 5s
timeout client 120s
timeout server 120s
timeout http-request 5s
timeout http-keep-alive 5s
option http-keep-alive
frontend http
mode http
bind *:80
default_backend servers1
backend servers1
mode http
balance roundrobin
server web1 web1:80 check
server web2 web2:80 check
server web3 web3:80 check
更新
使用 Wireshark,从客户端的角度来看,客户端 是 重复使用与 HAProxy 前端的相同套接字连接,直到超时到期。所以 keep-alive 似乎在客户端和前端之间工作。但是,我向网页添加了一个图像,以查看哪个后端服务器将为它提供服务,以及它是否与为 HTML 提供服务的服务器不同……并且它是不同的。在循环模式下,两个不同的后端服务器向同一个客户端提供内容,即使我启用了 keep-alive。
这一切在我看来 keep-alive 是 而不是 在前端和后端之间工作。如果我设置了 option http-server-close
,这是我期望的行为,但在使用 option http-keep-alive
时不会,这应该保持与服务器的连接打开。
- 您应该确保您的服务器不会关闭连接。
- 您应该在 HAProxy 的默认设置部分启用 "option prefer-last-server"。
- 您应该重新阅读 HAProxy 的 "option http-keep-alive" 文档:http://cbonte.github.io/haproxy-dconv/configuration-1.6.html#option%20http-keep-alive。
它明确指出:
If the client request has to go to another backend or another server due to content switching or the load balancing algorithm, the idle connection will immediately be closed and a new one re-opened. Option "prefer-last-server" is available to try optimize server selection so that if the server currently attached to an idle connection is usable, it will be used.
(因此第 2 点)
所以你的观察看起来很正常。
我对 HTTP Keep-Alive 的推理是否正确?这是我的假设:
- 在现代浏览器中,持久连接是默认设置,因此 连接:Keep-Alive 响应 header 不太可能由 HAProxy 发送那些客户。 不看到它并不一定意味着连接不持久。
- A Keep-Alive 意味着很短的持续时间,例如几百毫秒,在此期间客户端可以重复使用与同一服务器的相同连接(用于下载图像等用途,CSS 和 JavaScript 在同一页上)
- 可以通过 cookie 或 stick tables 实现更长的持久性
我问的原因是因为当我设置长 keep-alive 超时(通过 timeout http-keep-alive
)时,键入 F5 会以同样快的速度快速加载不同的后端服务器,在所有三个服务器之间轮换而没有任何效果来自 keep-alive。我本以为如果我在 keep-alive 5 秒超时期间按 F5,我仍然会得到相同的后端服务器。
我是不是想错了?
这是我的 HAproxy 配置,我将 keep-alive 超时设置为 5 秒:
defaults
timeout connect 5s
timeout client 120s
timeout server 120s
timeout http-request 5s
timeout http-keep-alive 5s
option http-keep-alive
frontend http
mode http
bind *:80
default_backend servers1
backend servers1
mode http
balance roundrobin
server web1 web1:80 check
server web2 web2:80 check
server web3 web3:80 check
更新
使用 Wireshark,从客户端的角度来看,客户端 是 重复使用与 HAProxy 前端的相同套接字连接,直到超时到期。所以 keep-alive 似乎在客户端和前端之间工作。但是,我向网页添加了一个图像,以查看哪个后端服务器将为它提供服务,以及它是否与为 HTML 提供服务的服务器不同……并且它是不同的。在循环模式下,两个不同的后端服务器向同一个客户端提供内容,即使我启用了 keep-alive。
这一切在我看来 keep-alive 是 而不是 在前端和后端之间工作。如果我设置了 option http-server-close
,这是我期望的行为,但在使用 option http-keep-alive
时不会,这应该保持与服务器的连接打开。
- 您应该确保您的服务器不会关闭连接。
- 您应该在 HAProxy 的默认设置部分启用 "option prefer-last-server"。
- 您应该重新阅读 HAProxy 的 "option http-keep-alive" 文档:http://cbonte.github.io/haproxy-dconv/configuration-1.6.html#option%20http-keep-alive。 它明确指出:
If the client request has to go to another backend or another server due to content switching or the load balancing algorithm, the idle connection will immediately be closed and a new one re-opened. Option "prefer-last-server" is available to try optimize server selection so that if the server currently attached to an idle connection is usable, it will be used.
(因此第 2 点)
所以你的观察看起来很正常。