5

イベントレットワーカーとgunicornを使用して、HerokuでFlaskアプリを実行しています。私のアプリの特定のルートは、かなり分厚いフィールド(最大で500KB程度)を含むPOSTデータ(x-www-form-urlencoded)を頻繁に受信します。

これはローカルで実行している場合は正常に機能しますが、Herokuでは、そのルートへのリクエストが完了するまでに5〜30秒かかります。また、時間のほぼ100%がrequest.formへの最初のアクセスに費やされます。

t = time.time()
action = str(request.form['action'])
dt = time.time() - t  # Often 10 seconds or more!

これは、Newrelicの低速リクエストトレースでも確認されています。報告されたCPU時間は通常1ミリ秒未満であるため、データベース操作には数ミリ秒があり、Pythonコードでは膨大な時間がI/Oの待機に費やされているようです。

本番環境で使用しているのと同じgunicorn/eventletセットアップを使用して、ローカル環境でこれを完全に再現することはできませんでした。組み込みのデバッグWSGIサーバーでさえ、これらの要求に対して非常に高速です。

何がうまくいかないのか誰かが知っていますか?それはFlaskの問題ですか、それともHerokuサポートに連絡する必要があるものですか?

4

1 に答える 1

3

私は何が起こっているのかを正確に理解したと思います。TL; DRサーバー側では実際にはまったく遅くはありませんでした。Newrelicの報告された応答時間に惑わされました!

@AllanAndersonが提案したのと同じコードをdotCloudのサンドボックスで実行してみました。最初に、縮小されたテストケースを作成しました。約900KBのデータがプリロードされたいくつかの非表示フィールドを持つ単純なHTMLフォームと、request.formディクショナリからの読み取りと、を使用して各アクセスの経過時間を測定する以外は何もしないビュー関数です。 time.time()。

Herokuでは、結果は次のようになりました。

5.87100 seconds: read field "p1": 786432 bytes
0.00019 seconds: read field "p2": 131072 bytes
0.00003 seconds: read field "p3": 12288 bytes
0.00001 seconds: read field "p4": 1024 bytes

そしてdotCloudで:

0.00096 seconds: read field "p1": 786432 bytes
0.00019 seconds: read field "p2": 131072 bytes
0.00003 seconds: read field "p3": 12288 bytes
0.00001 seconds: read field "p4": 1024 bytes

しかし、私のブラウザでは両方のテストに同じ時間がかかるようでした...そして今ではおそらくこの「問題」に対する本当の答えを推測しているでしょう。:-)

Herokuのgunicornは、ヘッダーが受信されるとすぐにビュー機能を実行しており、request.formへの最初のアクセスは、残りのリクエストが受信されるまでブロックされていたことがわかりました。そのため、Newrelicは、これらの途方もなく遅い応答時間をすべて見ました。これは、実際には、安っぽいネットワーク接続を介してPOSTデータをアップロードした結果でした。dotCloudのセットアップは、リクエスト全体が受信されるまで待機しているようです。

これにより、Newrelicのメトリックの有用性は低下しますが、実際にはエンドユーザーエクスペリエンスの問題ではありません。

于 2013-02-12T23:48:41.527 に答える