我正在使用nbsrv
ACL 规则来确定是否应该允许该请求(1)。
示例配置:
defaults
mode http
frontend front_www
listen 0.0.0.0:80
acl acl_backend_down nbsrv(back_www) lt 1
http-request deny if acl_backend_down
default_backend back_www
backend back_wwww
server s1 1.2.3.1:80 check
server s2 1.2.3.2:80 check
server haproxy-dc2 1.3.4.1:80 check backup
通过这种配置,我预计当 s1 和 s2 关闭时,nbserv 将为 0,从而返回 HTTP 403。
不幸的是,直到我关闭备份服务器(haproxy-dc2)它才会发送 403。
如果我将 ACL 规则更改为少于两个(即):
acl acl_backend_down nbsrv(back_www) lt 2
然后它按照我预期的方式运行:当后端只有一个主服务器可用时,它会发送 403。
我认为小于运算符可能有些奇怪,所以将其改为eq 0
,但这也不起作用。
是否有某种方法可以强制 nbsrv 按照我期望的方式工作,或者有其他方法可以检测后端的所有主服务器是否已关闭?
(1) 此 ACL 是更大规则集的一部分,我将其简化为最小的可重现示例。如果您有其他解决方案可以让我检测我们是否在使用备份服务器,请告诉我。大局的 tl;dr 是允许两个 haproxy 实例相互故障转移,但防止无限循环(例如,如果 dc01 的后端关闭,则对 dc02 对 dc01 的健康检查的响应应为 403/down)
电子邮件:
为了补充一些关于@gf_ 解决方案的评论背景...我们的生产环境相当复杂。有多个备份+多个 DC,每个实例都有许多后端(多个应用程序,加上内容切换)
对于监控 - 实例之间有内部 HAProxy 健康检查,还有通过 collectd+zabbix 的外部监控,如果所有后端服务器都不健康,它将向我们发送警报。知道没有可用的备份意味着我们可以提高警报的优先级。
所以,这就是为什么我简化了这个例子,仅仅展示nbsrv(back_www) lt 1
我试图修复的东西。
目前我倾向于使用 lt 2,并且假设如果只有一个盒子启动,我们不希望其他 LB 在这里发生故障。
答案1
我不完全确定以下内容是否适合您,并且现在无法测试,但也许它仍然有帮助:
HAProxy config of dc01
:
defaults
mode http
frontend front_www
listen 0.0.0.0:80
acl acl_backend_down nbsrv(back_www) lt 1
monitor-uri /health
monitor fail if acl_backend_down
use_backend dc02 if acl_backend_down
default_backend back_www
backend back_wwww
server s1 1.2.3.1:80 check
server s2 1.2.3.2:80 check
backend dc02
server haproxy-dc2 1.3.4.1:80 check
利用监控 uri和监控失败指令并检查/health
(dc02
反之亦然)。/health
应该报告HTTP 200
是否至少有一个后端活着并且健康,否则HTTP 503
。