Django,sleep()暂停所有进程,但只有没有GET参数?

时间:2013-02-26 08:18:40

标签: python django sleep

使用Django(由Webfaction托管),我有以下代码

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

当我访问我的网址时,这是通过Django执行的,www.mysite.com

我两次之后立即输入网址。我看到它的方式,这些都应该在10秒后完成。但是,第二个呼叫等待第一个呼叫,并在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运行它。

3 个答案:

答案 0 :(得分:8)

正如Gjordis所指出的,睡眠会暂停当前线程。我看过Webfaction,看起来他们正在使用WSGI来运行Django的服务实例。这意味着,每次请求进入时,Apache都会查看当前正在运行的工作进程数(即每个运行Django实例的进程)。如果没有/要查看它将产生额外的工作人员并将请求交给他们。

以下是我认为你的情况:

  • 首先获得资源A的GET请求.Apache使用正在运行的工作者(或启动一个新工作者)
  • 工人睡了10秒
  • 在此期间,资源A的新请求进入.Apache看到它正在请求相同的资源并将其发送给与请求A相同的工作者。我猜这里的假设是最近处理请求的工作者一个特定的资源,工人更有可能缓存/预处理某些信息,以便更快地处理这个请求
  • 这导致20秒的阻止,因为只有工人等待2次10秒

这种行为在99%的时间内完全有意义,因此默认情况下这样做是合乎逻辑的。

但是,如果您更改第二个请求的请求资源(通过添加GET参数),Apache将假设这是一个不同的资源并将启动另一个工作程序(因为第一个已经“忙”(Apache无法知道)你没有做任何艰苦的工作。)因为现在有两个工人,都等了10秒,总时间减少到10秒。

<小时/> 另外,我假设您的设计出现了错误。几乎没有任何情况我可以想到尽可能快地不响应HTTP请求是明智的。毕竟,你想在最短的时间内尽可能多地提出请求,所以睡10秒是你可以做的最适得其反的事情。我建议你创建一个新问题并说明你想要达到的实际目标是什么。我很确定有一个更明智的解决方案!

答案 1 :(得分:3)

假设您只使用run()运行Django服务器,默认情况下这会生成一个单线程服务器。如果在单线程进程上使用sleep,整个应用程序将冻结该休眠时间。

答案 2 :(得分:1)

可能只是您的浏览器将第二个请求排队,只有在第一个请求完成后才会执行。如果您要在同一浏览器中打开网址,请尝试使用两个不同的网址(例如Firefox和Chrome),或尝试使用wgetcurl从命令行执行请求。