web-dev-qa-db-ja.com

断続的なトラブルシューティングの助けが必要TCP HAProxyのタイムアウト

クライアントがTLS/SSLを介した単純なTCPベースのプロトコルを介してサーバーに接続するアプリケーションがあります。開発中、これはアプリケーションを構築している間、何ヶ月もの間うまく機能しました。最近起動の準備として、負荷分散の順序を容易にするために、HAProxyをミックスに追加しました。技術的にはすべてが機能しますが、問題は、クライアントに完全にランダムなタイムアウトが発生していることです。通常は一定ですが、約60秒で発生します。25秒後に発生する場合もあります。haproxyがTCP=接続を通知に転送し、完全に切断する場合、問題は多くの同時接続が何の理由もなく何度も中断され再接続されることを望んでいます。これは、他のことに加えて、パブリッシュ/サブスクライブインフラストラクチャに影響を与えます。クライアントはすぐに再接続できるほど十分スマートですが、それは私たちが望む動作ではありません。 serこれらのTCP SSLを介した接続を受け入れる責任があるverは、キープアライブを必要としません。先に進んで、HAProxy構成に表示されていない暗黙の値があり、これらのランダムタイムアウトが発生している、またはTCPキープアライブ)が必要なものがあると想定します。ただし、タイムアウトは常に一貫しているとは限りませんが、そうではないのではないかと思います。ドットが60秒だったとしたら、それは構成の問題だと確信するたびに。この特定のケースでは、必ずしも60秒とは限りません。設定は今のように見えます:

global
stats socket /home/haproxy/status user haproxy group haproxy
    log 127.0.0.1   local1 info
#   log 127.0.0.1   local5 info 
    maxconn 4096
    ulimit-n 8250
        # typically: /home/haproxy
    chroot /home/haproxy
    user haproxy    
    group haproxy
    daemon
    quiet
    pidfile /home/haproxy/haproxy.pid

defaults
    log global
    mode    http
    option  httplog
    option  dontlognull
    retries 3
    option redispatch
    maxconn 2000
    contimeout  5000
    clitimeout  60000
    srvtimeout  60000

# Configuration for one application:
# Example: listen myapp 0.0.0.0:80
listen www 0.0.0.0:443
        mode tcp
        balance leastconn
    # Example server line (with optional cookie and check included)
    # server    srv3.0 10.253.43.224:8000 srv03.0 check inter 2000 rise 2 fall 3
# Status port (by default, localhost only...for debugging purposes)
    server ANID3 10.0.1.2:8888 check inter 3000 rise 2 fall 3 maxconn 500
    server ANID1 10.0.1.3:8888 check inter 3000 rise 2 fall 3 maxconn 500
    server ANID2 10.0.1.4:8888 check inter 3000 rise 2 fall 3 maxconn 500

listen health 0.0.0.0:9999
        mode http
        balance roundrobin
        stats uri /haproxy-status

HAProxyをバイパスして、タイムアウトがなく、すべてが素晴らしくてダンディな単一のアプリサーバーに直接アクセスすることで、HAProxyが問題であることを確認しました。 2つのhaproxyサーバーのいずれかを介してルーティングするとすぐに、25〜60秒の範囲でランダムな切断が発生します。

これをご覧いただきありがとうございます。非常に苛立たしいことですが、HAProxyがクライアントに何を期待しているのかを正確に理解していないことは間違いありません。

5
imaginative

接続を早期に閉じる理由はないはずです。それがどのように発生するのかさえわかりません。タイムアウトは60秒に設定されているため、60秒にする必要があります。

うーん、ちょっと待ってください、あなたは実行していませんか haproxy 内部でVM高速で実行されているクロックで?それはいくつかのVMで問題であり、クロックが時々遠くまで実行されます速すぎる(正しい速度の2倍以上)、または1分に1回の大きなジャンプで遅すぎる。Haproxyは、検出できる長すぎるポーズとタイムジャンプを防ぐ方法を知っていますが、速度が速すぎるとクロックが速すぎないように防御できませんシステムによって報告されます。

VMを使用している場合は、これを試すことができます。

$  while sleep 1; do date; done

これを1〜2分間実行します。正しい速度で動作しているかどうかを自分で確認してください。この厄介な問題を最後に観察してからしばらく経ちましたが、それが二度と起こらないという意味ではありません。

ところで、「option tcplog "TCPセクションで、ログを確認します。haproxyの観点から、タイムアウト、クライアントまたはサーバーの異常終了、およびその後の経過を確認します。 。

1
Willy Tarreau

これをテストできますか:

defaults  
    timeout client 60000  
    option http-server-close  

Clitimeoutの代わりに

https://code.google.com/p/haproxy-docs/wiki/http_server_close

0
Greg Askew

時間は可変であり、バックエンドが責任を負わないことを明確に確認しているため、タイムアウト設定である可能性は低いです。

奇妙なことに、それはおそらくサービスが再起動されるという解決策に私を導きます。

CronでHAProxyを再起動しているものがある場合(たとえば、monit-60秒ごとにポーリングします)、セッションが終了するまでに最大60秒、またはそれより短くなる可能性があります。

HAProxyで稼働時間を再確認し、それが常に1分程度未満であるかどうかを確認してください。答えがあります。

また、HAProxyからの統計を確認して、ハードセッションの制限に達していないことを確認し、代替タイムアウトが発生していないことを確認することもできます。 maxqueue未満のリクエストがすでにキューにある場合、timeout queue秒。タイムアウト後、不飽和サーバーが見つからない場合、要求はドロップされます。

これを試して、私はこの問題を修正しました。

listen mysql-slaves
bind 0.0.0.0:3306
mode tcp
maxconn 20000
option mysql-check user haproxy
balance roundrobin
contimeout 5000
clitimeout 50000
srvtimeout 50000
....
0
nor