9

目標:

非常に単純なシナリオですべての Nginx プロキシ タイムアウト パラメータをテストしたいと思います。私の最初のアプローチは、非常に単純な HTTP サーバーを作成し、いくつかのタイムアウトを設定することでした。

  1. リッスンと受け入れの間でproxy_connect_timeoutをテストする
  2. 受け入れと読み取りの間でproxy_send_timeoutをテストします
  3. 読み取りとテスト送信の

テスト:

1) サーバーコード (python):

import socket
import os
import time
import threading

def http_resp(conn):
    conn.send("HTTP/1.1 200 OK\r\n")
    conn.send("Content-Length: 0\r\n")
    conn.send("Content-Type: text/xml\r\n\r\n\r\n")

def do(conn, addr):
    print 'Connected by', addr
    print 'Sleeping before reading data...'
    time.sleep(0) # Set to test proxy_send_timeout
    data = conn.recv(1024)
    print 'Sleeping before sending data...'
    time.sleep(0) # Set to test proxy_read_timeout
    http_resp(conn)
    print 'End of data stream, closing connection'
    conn.close()

def main():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(('', int(os.environ['PORT'])))
    s.listen(1)
    print 'Sleeping before accept...'
    time.sleep(130) # Set to test proxy_connect_timeout
    while 1:
        conn, addr = s.accept()
        t = threading.Thread(target=do, args=(conn, addr))
        t.start()

if __name__ == "__main__":
    main()

2) Nginx の設定:

proxy_connect_timeoutを明示的に設定し、ローカル HTTP サーバーを指すproxy_passを追加することで、Nginx のデフォルト構成を拡張しました。

    location / {
        proxy_pass http://localhost:8888;
        proxy_connect_timeout 200;
    }

3) 観察:

proxy_connect_timeout - 200 秒に設定し、リッスンと受け入れの間に 130 秒だけスリープしても、Nginx は ~60 秒後に 504 を返します。これは、デフォルトのproxy_read_timeout値が原因である可能性があります。proxy_read_timeoutが非常に早い段階 (受け入れる前) に接続にどのように影響するかを理解していません。ここでは200を期待します。説明してください!

proxy_send_timeout - proxy_send_timeoutをテストする私のアプローチが正しいかどうかわかりません - 私はまだこのパラメータを正しく理解していないと思います。結局、受け入れと読み取りの間の遅延は、proxy_send_timeout を強制しません。

proxy_read_timeout - かなり単純なようです。読み取りと書き込みの間の遅延を設定すると、仕事ができます。

したがって、私の仮定は間違っていると思います。おそらく、proxy_connect と proxy_send のタイムアウトを正しく理解していません。可能であれば上記のテストを使用して(または必要に応じて変更して)説明してください。

4

1 に答える 1

5

ドキュメントによると、接続タイムアウトは 75 秒を超えることはできません。これが、予想よりも早くタイムアウトになる理由を説明している可能性があります。ただし、肯定的ではありません。低レベルの python ソケット ライブラリを実際に使用したことがないため、プログラムで実際に s.accept() を呼び出す前に、低レベルでプールへの接続を受け入れている可能性があります。

送信タイムアウトは、アップストリーム サーバーに向かう 2 つのデータ チャンク間の時間を測定することによって機能します。応答全体を 1 つのチャンクで送信しているため、実装では、送信タイムアウトではなく、読み取りタイムアウトに再び達していると思います。1 つのチャンクを送信し、送信タイムアウトを過ぎて残りの応答を送信し、接続を閉じる場合は、送信タイムアウトに達する必要があります。

于 2013-06-24T19:04:14.763 に答える