问题
我使用 haproxy 来平衡 Web 服务器负载。我使用带有附加 cookie 的会话持久性,因为某些应用程序使用会话文件,而这些文件在服务器之间不同步。
我想禁用服务器进行维护,但不中断会话。因此,我想允许现有客户端继续其应用程序会话,但不接受新客户端。
haproxy 行为
- 我将服务器设置为“正在维护”
- 如果客户端设置了 cookie,则使用服务器,即使标记为“进入维护阶段”
- 如果有新客户端(没有 cookie)到来,则将其定向到另一台服务器
- 在所有客户端结束其应用程序会话之后,将不再有客户端将 cookie 设置到此特定服务器,并且我最好在不打扰用户的情况下将其关闭。
您认为通过某些 haproxy 配置可以实现这一点吗?或者有更聪明的方法可以做到这一点?
其他方法
满足此需求的其他方法的非详尽列表:
- 在服务器之间同步会话文件(需要一种方法来同步多个服务器之间的文件,或一个通用的单一挂载点)
- 使用数据库存储会话信息(需要更改应用程序行为)
更多细节
我使用这种配置:
frontend https-in
bind xxx.xxx.xxx.xxx:443 ssl crt /etc/haproxy/ssl/_default.pem crt /etc/haproxy/ssl
reqadd X-Forwarded-Proto:\ https
acl APP1 hdr(host) -i APP1.atac.local
use_backend APP1 if APP1
default_backend _default
backend APP1
redirect scheme https if !{ ssl_fc }
mode http
balance roundrobin
cookie HAPROXY_SESSION insert indirect
option httpchk HEAD /haproxy_test_page.php HTTP/1.0\nUser-Agent:\ HAProxy
server SRV1 SRV1_IP:PORT cookie SRV1 check
server SRV2 SRV2_IP:PORT cookie SRV2 check
如果我只是禁用 SRV1(使用 haproxy cli 命令),我认为在当前 HTTP“会话”结束后,在 SRV1 上打开的所有应用程序会话都将中断。对吗?
答案1
使用 Web 管理界面将服务器置于排水模式。这提供了您正在寻找的确切功能。
有关 Web 管理界面的详细信息 -https://github.com/Aidaho12/haproxy-wi
答案2
答案3
对于想要从 HAProxy 容器中排出后端的未来读者......
docker exec $(docker ps | grep haproxy | awk '{print $1}') bash -c 'echo "set server backend_name/svc_name state drain" | nc -U /haproxy.sock'
注意:
路径/haproxy.sock
是您在文件中设置的路径haproxy.cfg
[例如stats socket /haproxy.sock mode 660 level admin
]
答案4
其他方法
在服务器之间同步会话文件(需要一种方法来同步多个服务器之间的文件,或一个通用的单一挂载点)
如果您的后端服务器使用 PHP 作为应用程序,则可以使用 Memcache 同步它们之间的会话。
还Couchbase 服务器可以开箱即用地进行 memcache 复制。
当然,如果只使用 Couchbase-server 进行会话复制,那就有点大材小用了 :)