6

Django (Webfaction がホスト) を使用して、次のコードを作成しました。

import time
def my_function(request):
    time.sleep(10)
    return HttpResponse("Done")

これは、自分の URL www.mysite.com にアクセスすると、Django を介して実行されます。

URL を 2 回入力します。私の見方では、これらは両方とも 10 秒後に終了するはずです。ただし、2 番目の呼び出しは最初の呼び出しを待機し、20 秒後に終了します。

ただし、ダミーの GET パラメータ www.mysite.com?dummy=1 と www.mysite.com?dummy=2 を入力すると、どちらも 10 秒後に終了します。したがって、両方を同時に実行することは可能です。

sleep() のスコープが何らかの形でグローバルであるかのようです?? パラメータを入力すると、同じプロセスではなく別のプロセスとして実行されるのでしょうか???

Webfaction によってホストされています。httpd.conf には次のものがあります。

KeepAlive Off
Listen 30961
MaxSpareThreads 3
MinSpareThreads 1
ServerLimit 1
SetEnvIf X-Forwarded-SSL on HTTPS=1
ThreadsPerChild 5

sleep() を使用できる必要があり、それがすべてを停止していないことを信頼する必要があります。それで、何が起きていて、それを修正する方法は?

編集: Webfaction は Apache を使用してこれを実行します。

4

3 に答える 3

8

Gjordis が指摘したように、sleep は現在のスレッドを一時停止します。Webfaction を調べたところ、Django のサービング インスタンスを実行するために WSGI を使用しているようです。つまり、リクエストが来るたびに、Apache は現在実行中のワーカー プロセス (それぞれが Django のインスタンスを実行するプロセス) の数を調べます。何も表示されない場合は、追加のワーカーが生成され、リクエストが渡されます。

あなたの状況で起こっていると私が思うことは次のとおりです。

  • リソース A に対する最初の GET リクエストが送信されます。Apache は実行中のワーカーを使用します (または新しいワーカーを開始します)。
  • ワーカーは 10 秒間眠ります
  • この間に、リソース A の新しいリクエストが届きます。Apache は、それが同じリソースをリクエストしていることを認識し、リクエスト A と同じワーカーに送信します。ここで想定しているのは、ワーカーが特定のリソースのリクエストを最近処理したということです。このリクエストをより速く処理できるように、ワーカーが何らかの情報をキャッシュ/前処理/何でも保持している可能性が高くなります。
  • 10 秒の 2 倍を待機するワーカーのみがあるため、これにより 20 秒のブロックが発生します。

この動作は 99% の確率で完全に理にかなっているため、デフォルトでこれを行うのが論理的です。

ただし、2 番目の要求で要求されたリソースを (GET パラメータを追加することによって) 変更すると、Apache はこれが別のリソースであると想定し、別のワーカーを開始します (最初のワーカーはすでに「ビジー」であるため (Apache はあなたが2 人のワーカーが存在するため、両方とも 10 秒待機すると、合計時間は 10 秒に短縮されます。


さらに、あなたのデザイン に何か問題があると思います。HTTP リクエストにできるだけ早く応答しないことが賢明であると考えることができるケースはほとんどありません。結局のところ、最短時間でできるだけ多くのリクエストを処理したいので、10 秒間スリープ状態にするのは最も逆効果です。新しい質問を作成し、達成しようとしている実際の目標を述べることをお勧めします。これにはもっと賢明な解決策があると確信しています!

于 2013-02-26T09:12:58.617 に答える
4

Django サーバーを だけで実行すると仮定するとrun()、デフォルトでは、これにより単一のスレッドサーバーが作成されます。シングル スレッド プロセスでスリープを使用すると、アプリケーション全体がそのスリープ時間の間フリーズします。

于 2013-02-26T08:24:18.450 に答える
1

単純に、最初のリクエストが完了した後にのみ実行されるように、ブラウザが 2 番目のリクエストをキューに入れている可能性があります。URL を同じブラウザで開いている場合は、2 つの異なるブラウザ (Firefox と Chrome など) を使用するか、代わりにwgetorを使用してコマンド ラインからリクエストを実行してみてください。curl

于 2014-01-09T20:34:43.397 に答える