HAProxy 间歇性 504 错误

Ped*_*dro 4 timeout haproxy 504

数周以来,我一直在为这个问题而苦苦挣扎,但我的想法已经不多了。我运行 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
Run Code Online (Sandbox Code Playgroud)

我自己经历过那些访问网站的 504。我所要做的就是刷新页面,它会立即再次运行。在获得那些 504 之前,我不必等待 120 秒(服务器超时),它们会根据请求立即出现。

来自日志的示例(清理)错误:

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"
Run Code Online (Sandbox Code Playgroud)

我有类似的 s3 后端日志。我查看了文档以了解什么sR意思。第一个字符是报告导致会话终止的第一个事件的代码:

s :等待服务器发送或接收数据时服务器端超时。

第二个字符表示关闭时的 TCP 或 HTTP 会话状态:

R :代理正在等待来自客户端的完整、有效的 REQUEST(仅限 HTTP 模式)。没有任何内容发送到任何服务器。

这种组合sR对我来说没有意义。服务器超时怎么会因为设置为 120 秒而过期?为什么第二个字母是指客户?这些字母看起来很矛盾。

0/0/1/-1/1部分代表时间。长话短说,它表明我们不等待 120 秒,它立即失败。

s3 和 Node.js 后端都有这个完全相同的问题。我曾经用 Nginx 处理过整个事情,它运行良好,所以我相信这个问题与我的配置无关。关于调试这个有什么建议或建议吗?

Ped*_*dro 7

我想我终于想通了。解决方案包括增加timeout值:

timeout connect 20s
timeout client  10m
timeout server  10m
Run Code Online (Sandbox Code Playgroud)

我不确定为什么将客户端/服务器超时从 2 分钟增加到 10 分钟解决了这个问题。我相信这与keep-aliveHAProxy 与 S3/Node 保持开放连接的事实有关。

希望这可以帮助!