web-dev-qa-db-ja.com

HAProxyでの断続的な504エラー

私はこの問題に何週間も苦労しており、アイデアが不足しています。 HAProxyを実行して、リクエストのパス/ヘッダーに基づいて3つのバックエンド間でリクエストをプロキシします。

私のバックエンドは:

  • Amazon S3バケット
  • Node.jsアプリ(2サーバー)
  • Prerender.ioというサービス

最後のバックエンド(prerender.io)には問題がないようです(トラフィックはほとんどありません)。他の2つはランダムに504エラーをクライアントに返します(ログによると約1分ごとですが、明確なパターンはありません)。

これが私の(無害化された)設定です:

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人を経験しました。私がしなければならないのは、ページを更新するだけで、すぐに再び機能します。これらの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"

S3バックエンドにも同様のログがあります。ドキュメントを調べて、sRの意味を理解しました。最初の文字は、セッションを終了させた最初のイベントを報告するコードです。

s:サーバーがデータを送受信するのを待っている間にサーバー側のタイムアウトが期限切れになりました。

2番目の文字は、TCPまたは閉じられたときのHTTPセッション状態を示します。

R:プロキシはクライアントからの完全で有効なREQUESTを待っていました(HTTPモードのみ)。どのサーバーにも何も送信されませんでした。

この組み合わせsRは私には意味がありません。サーバーのタイムアウトが120秒に設定されているため、どのように期限切れになるのですか?そして、なぜ2番目の文字がクライアントを指しているのですか?それらの手紙は矛盾しているようです。

0/0/1/-1/1部分は時間を表します。長い話は、120秒待たないことを示し、すぐに失敗します。

S3とNode.jsの両方のバックエンドで、このまったく同じ問題が発生します。私は以前はすべてNginxを前面に出していましたが、問題なく機能していたため、この問題は私の構成とは関係がないと確信しています。これをデバッグするためのアドバイスや提案はありますか?

2
Pedro

ようやく理解できたと思います。解決策は、timeout値を増やすことでした。

timeout connect 20s
timeout client  10m
timeout server  10m

クライアント/サーバーのタイムアウトを2分から10分に増やすことで問題が解決した理由がわかりません。私はそれがkeep-aliveと関係があると思います、そしてHAProxyがS3/Nodeとの開いた接続を維持しているという事実。

お役に立てれば!

6
Pedro

私もこの問題にぶつかり、v1.7.10のバグであることが判明しました。

https://discourse.haproxy.org/t/intermittent-504-errors-and-sr​​-after-upgrade-to-1-7-10/2029

V1.7.11 +にアップグレードすると問題が修正されます。

2
Joe P