我在ACL规则中使用nbsrv来确定是否允许请求(1)。
configuration示例:
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
有了这个configuration,我期望当s1和s2closures时,nbserv将会是0,并因此返回一个HTTP 403。
不幸的是,直到我取下备份服务器(haproxy-dc2)才发送403。
如果我将ACL规则更改为less于两个(即):
acl acl_backend_down nbsrv(back_www) lt 2
然后它按照我预期的方式运行:当后端只有一个主要的可用的时候,它发送403。
我想也许有一些奇怪的小于运营商,所以改为eq 0 ,但这也不起作用。
有没有办法强制nbsrv像我所期待的那样工作,或者有其他方式来检测后端的所有初选是否失效?
(1)这个ACL是更大规则集的一部分,我把它简化成最小的可重现的例子。 如果您有其他解决scheme可以让我检测是否使用备份服务器,请告诉我。 大图的tl; dr允许两个haproxy实例相互故障转移,但是防止无限循环(例如,如果dc01的后端处于closures状态,那么对dc01的dc01健康检查的响应应该是403 / down)
E:
在下面的@ gf_解决scheme的评论中添加一些上下文…我们的生产环境相当复杂。 有多个备份+多个DC,每个实例有许多后端(多个应用程序,加上内容切换)
对于监控 – 实例之间的内部HAProxy健康检查,还可以通过collectd + zabbix进行外部监控,如果所有后端服务器都不健康,则会向我们发送警报。 知道没有可用的备份意味着我们可以提高警报的优先级。
所以,这就是为什么我把这个例子简化为只显示nbsrv(back_www) lt 1作为我想要解决的问题。
目前我倾向于与2一起去,并假设如果只有一个盒子,我们不希望其他LB在这里失败。
我不完全确定下面的内容是否适用于你,现在还不能testing,但也许还是有帮助的:
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
利用monitor-uri并监视失败指令并检查dc02 /health (反之亦然)。 /health应该报告HTTP 200如果至less一个后端是活着和健康的,否则HTTP 503 。