HAProxy & Consul-template:缩减时重试请求

HAProxy & Consul-template : retry request when scaling down

我正在研究基于 Docker、registrator、consul 和 HAProxy 的微服务架构。

我也在使用 Consul-template 动态生成 HAProxy 配置文件。一切正常:当我添加同一微服务的多个实例时,HAProxy 配置会立即更新,并使用循环策略正确分派请求。

当我删除一些实例(按比例缩小)时出现问题。如果容器在请求 运行 时关闭,我有一个错误。

我是 HAProxy 的新手,所以有没有办法配置 HAProxy 让它在容器消失时重试对另一个端点的失败请求?

精度:我正在为我的前端和后端使用第 7 层路由模式(http 模式)。这是我的领事模板文件的一个小样本:

backend hello-backend
    balance roundrobin
    mode http
    {{range service "HelloWorld" }}server {{.Node}} {{.Address}}:{{.Port}} check
    {{end}}

    # Path stripping
    reqrep ^([^\ ]*)\ /hello/(.*) \ /

frontend http
    bind *:8080
    mode http

    acl url_hello path_beg /hello
    use_backend hello-backend if url_hello

感谢您的帮助。

HAProxy 无法重新发送已发送到后端的请求。

这是创建者威利 post 的论坛。

redispatch only happens when the request is still in haproxy. Once it has been sent, it is cannot be performed. It must not be performed either for non idempotent requests, because there is no way to know whether some processing has begun on the server before it died and returned an RST.

http://haproxy.formilux.narkive.com/nGKXq6WU/problems-with-haproxy-down-servers-and-503-errors

post 已经很老了,但根据最近的讨论,它仍然适用。如果请求大于 tune.bufsize(默认值约为 16KB iirc),那么 HAProxy 甚至在发生错误时甚至没有将整个请求保留在内存中。

幸运的是(对于工艺)和不幸的是(为了实际实用程序的目的),Willy 一直坚持 HAProxy 的正确行为,他确实是正确的,重试一次非幂等请求是不合适的它们已被发送到后端服务器,因为在某些情况下这肯定会导致重复处理。

对于 GET 请求,根据定义,它应该是幂等的(GET 请求必须是可重复的而不会产生任何后果,否则它不应该被设计为使用 GET --它应该是 POST 或另一个动词)有一个可行的论点,即重新发送到不同的后端将是一个合法的行动过程,但目前也不支持。

相比之下,Varnish does 支持重做,我已经(在 HAProxy 后面)成功地使用了 GET 请求,我有在线和近线存储相同的对象名称空间。旧的 "unpopular" 文件被迁移到近线(更慢,更便宜)存储,但所有请求都发送到在线存储,如果在线 returns a 则重试目的地为近线404. 但是,除了 GET.

之外,我从未尝试过此请求

理想情况下,您的解决方案是宣布您的后端不健康,可能是在关闭之前故意让他们的 HTTP 健康检查失败一段时间。一种相当简单的方法是运行状况检查要求存在静态文件,该文件在关闭前从后端删除。或者,您可以通过 stats/admin UI 或套接字请求 HAProxy 认为后端处于维护模式,以防止发起更多请求,同时允许 运行 请求耗尽。