我已经为这个问题苦苦挣扎了好几个星期,我已经没有主意了。我运行 HAProxy,根据请求的路径/标头在 3 个后端之间代理请求。
我的后端是:
- Amazon S3 存储桶
- Node.js 应用程序(2 台服务器)
- 一个名为prerender.io的服务
最后一个后端 (prerender.io) 似乎没有任何问题(尽管它的流量很少)。另外两个后端会随机向客户端返回 504 错误(根据日志,大约每分钟一次,但没有明确的规律)。
这是我的(已清理的)配置:
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5s
timeout client 120s
timeout server 120s
frontend foobar
mode http
bind *:80
bind *:443 ssl crt /etc/ssl/certs/foobar.com.pem
redirect scheme https code 301 if !{ ssl_fc }
default_backend s3
acl api path_beg -i /api/
use_backend node if api
acl user-agent-bot hdr_sub(User-Agent) -i baiduspider twitterbot facebookexternalhit
use_backend prerender if user-agent-bot
backend s3
mode http
http-request set-path /index.html
reqirep ^Host: Host:\ my-bucket.s3-website-us-east-1.amazonaws.com
reqidel ^Authorization:.*
rspidel ^x-amz-id-2:.*
rspidel ^x-amz-request-id:.*
server s3 my-bucket.s3-website-us-east-1.amazonaws.com:80 check inter 5000
backend node
mode http
balance roundrobin
option forwardfor
server api01 1.2.3.4:3333 check
server api02 5.6.7.8:3333 check
backend prerender
mode http
server prerender service.prerender.io:443 check inter 5000 ssl verify none
http-request set-header X-Prerender-Token my-secret-token
reqrep ^([^\ ]*)\ /(.*)$ \1\ /https://app.wwoof.fr/\2
我自己在访问网站时也遇到过 504 错误。我只需刷新页面,它就会立即恢复正常。我不需要等待 120 秒(服务器超时)才能收到这些 504 错误,它们会在请求后立即出现。
日志中的示例(已清理的)错误:
Sep 28 14:27:13 node/api01 0/0/1/-1/1 504 195 - - sR-- 38/38/30/14/0 0/0 "GET /api/hosts/2266 HTTP/1.1"
Sep 28 14:34:15 node/api02 0/0/0/-1/0 504 195 - - sR-- 55/55/41/25/0 0/0 "GET /api/hosts/4719 HTTP/1.1"
Sep 28 14:34:15 node/api01 0/0/1/-1/1 504 195 - - sR-- 54/54/41/16/0 0/0 "GET /api/hosts/2989 HTTP/1.1"
Sep 28 14:38:41 node/api01 0/0/1/-1/1 504 195 - - sR-- 50/50/47/25/0 0/0 "POST /api/users HTTP/1.1"
Sep 28 14:42:13 node/api02 0/0/1/-1/1 504 195 - - sR-- 134/134/102/49/0 0/0 "POST /api/users HTTP/1.1"
Sep 28 14:42:29 node/api02 0/0/1/-1/1 504 195 - - sR-- 130/130/105/51/0 0/0 "GET /api/hosts/1634 HTTP/1.1"
我有类似的 s3 后端日志。我查看了文档以了解其sR
含义。第一个字符是报告导致会话终止的第一个事件的代码:
s :等待服务器发送或接收数据的服务器端超时时间已到。
第二个字符表示关闭时的 TCP 或 HTTP 会话状态:
R :代理正在等待来自客户端的完整、有效请求(仅限 HTTP 模式)。未向任何服务器发送任何内容。
这种组合sR
对我来说毫无意义。服务器超时时间设置为 120 秒,它怎么会过期呢?第二个字母为什么指的是客户端?这两个字母似乎自相矛盾。
该0/0/1/-1/1
部分代表时间。长话短说,它表示我们不等待 120 秒,它会立即失败。
s3 和 Node.js 后端都存在同样的问题。我以前用 Nginx 来处理整个事情,而且它运行良好,所以我确信这个问题与我的配置无关。有什么建议或建议可以调试这个问题吗?
答案1
我想我终于明白了。解决方案是增加timeout
值:
timeout connect 20s
timeout client 10m
timeout server 10m
我不确定为什么将客户端/服务器超时从 2 分钟增加到 10 分钟可以解决问题。我认为这与keep-alive
HAProxy 与 S3/Node 保持开放连接有关。
希望这可以帮助!
答案2
我也遇到了这个问题,结果是 v1.7.10 中的一个错误:
https://discourse.haproxy.org/t/intermittent-504-errors-and-sr-after-upgrade-to-1-7-10/2029
升级到 v1.7.11+ 可解决该问题。