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

时间:2016-08-26 07:28:50

标签: haproxy consul consul-template

我正在开发基于Docker,registrator,consul和HAProxy的微服务架构。

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

当我删除一些实例(缩小)时,我的问题就出现了。如果在请求运行时关闭容器,则会出错。

我是HAProxy的新手,所以有没有办法配置HAProxy,告诉它如果容器消失,重试失败的请求到另一个端点?

精确度:我正在为我的前端和后端使用layer7路由模式(模式http)。以下是我的consul-template文件的一些示例:

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

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

frontend http
    bind *:8080
    mode http

    acl url_hello path_beg /hello
    use_backend hello-backend if url_hello

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

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

这是来自创作者威利的论坛帖子。

  

redispatch仅在请求仍处于haproxy时发生。一旦发送,就无法执行。它不能对非幂等请求执行,因为无法知道服务器上的某些处理是否已经开始并且返回RST。

     

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

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

幸运的是(对于手艺而言)并且不幸的是(出于现实用途的目的),Willy一直坚持HAProxy的正确行为,并且他确实是正确的,一旦他们有了非幂等请求就不合适已被发送到后端服务器,因为肯定会导致重复处理。

对于GET请求,根据定义,它们应该是幂等的(GET请求必须是可重复的,没有后果,否则它不应该被设计为使用GET - 它应该已经POST或另一个动词那里有一个可行的论点,即重新发送到不同的后端将是一个合法的行动方案,但目前也不支持。

相比之下,

Varnish does支持重做,我已经使用(在HAProxy之后)成功GET请求,我有相同的在线和近线存储对象名称空间老了,不受欢迎"文件被迁移到近线(更慢,更便宜)的存储,但所有请求都被发送到在线存储,如果在线返回404,则重试目标为近线。但是,我从未尝试过这是GET以外的请求。

理想情况下,您的解决方案是将您的后端声明为不健康,可能是在关闭之前故意将HTTP运行状况检查失效。一种相当简单的方法是,运行状况检查需要存在静态文件,该文件在关闭之前从后端删除。或者,您可以通过stats / admin UI或套接字请求HAProxy认为后端处于维护模式,从而阻止在允许运行请求消耗的情况下启动更多请求。