web-dev-qa-db-ja.com

nginxで最初のバイトのタイムアウトを回避する方法

私はRubyOnRailsに、CDNサービスの背後にあるNGINXサーバーによってプロキシされたアプリケーションを持っています。 CDNには、応答の最初のバイトが60秒以内に到着しない場合、CDNサーバーが応答するという制限があります。

Error 503 first byte timeout

問題は、Rails側で処理されるのに60秒以上かかるリクエストがあることです。応答をハックして、応答が完了する前に数バイトを送信する方法はありますか?処理?どのように?

編集1

60年代は長い年月であり、これを回避する方法を考えています。それでも、60年代のリクエストが機能するようにする一時的なソリューションが必要です。 Ajaxを使用しても、一部のajax呼び出しには60秒以上かかり、同じ問題に分類されます。 tcp_nopushまたはtcp_nodelayオプションが機能しなかったのは、nginxがRailsアプリケーションの応答を待って、送信するヘッダーを知るためだと思います。したがって、解決策はハックする必要があるものかもしれません。 RubyOnRailsリクエスト/レスポンスサイクル内

2
Daniel Cukier

60秒以上かかるリクエストは、かなりの時間がかかります。アプリケーションを確認することをお勧めします。ページの読み込み時間が長すぎると、多くの訪問者がアプリを終了する可能性があります。 AJAXまたはwebsocketsなどを使用して、データを非同期にロードすることを検討することをお勧めします。

最初のバイトまでの時間は通常、応答本文ではなくヘッダーに適用されます。クライアントは早い段階でヘッダーを受信する必要があります。 CDNがリクエストをタイムアウトしたことを確認しますか? NGinxはリクエストもタイムアウトします。チェックする良い方法はcurlを使うことです:

curl -I -H "Host: <domain>" http://<ip of proxy>/request/uri 

(CDN IPではなく、プロキシの実際のIPを使用します)

-Iオプションは、応答ヘッダーを表示します。これにより、nginxによって返されるエラーコード(存在する場合)を適切に示すことができます。また、これがtcpの最初のバイトが参照するものであるため、要求ヘッダーを受信して​​いるかどうか、およびそれにかかる時間を確認することもできます。

ヘッダーがすぐに届かない場合は、次を使用してみてください。

http {
tcp_nopush off; 
tcp_nodelay on; # force socket to send buffer
}

ゲートウェイタイムアウトエラーなどが発生する場合は、次の構成オプションを試してください。

http {
keepalive_timeout 300;
proxy_connect_timeout 300;
proxy_read_timeout    300;
proxy_send_timeout    300;
}
3
Gregory Wolf