6

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

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

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

我输入了两次网址,紧随其后。在我看来,这两个都应该在 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 运行它。

4

3 回答 3

8

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

这是我认为在您的情况下发生的事情:

  • 对资源 A 的第一个 GET 请求进来。Apache 使用正在运行的工作人员(或启动一个新工作人员)
  • 工人睡了 10 秒
  • 在此期间,出现了对资源 A 的新请求。Apache 看到它正在请求相同的资源并将其发送给与请求 A 相同的工作人员。我想这里的假设是最近处理对特定资源的请求的工作人员工作人员更有可能缓存/预处理/任何信息,以便它可以更快地处理此请求
  • 这会导致 20 秒的阻塞,因为只有等待 2 次 10 秒的工作人员

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

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


此外,我认为您的设计有问题。几乎没有我能想到的不尽可能快地响应 HTTP 请求的情况。毕竟,你想在最短的时间内处理尽可能多的请求,所以睡 10 秒是你能做的最适得其反的事情。我建议您创建一个新问题并说明您要实现的实际目标。我很确定有一个更明智的解决方案!

于 2013-02-26T09:12:58.617 回答
4

假设您只使用 运行您的 Django-server run(),默认情况下这会创建一个单线程服务器。如果您在单线程进程上使用睡眠,则整个应用程序会冻结该睡眠时间。

于 2013-02-26T08:24:18.450 回答
1

可能只是您的浏览器正在排队等待仅在第一个请求完成后才执行的第二个请求。如果您在同一个浏览器中打开您的 URL,请尝试使用两个不同的浏览器(例如 Firefox 和 Chrome),或者尝试使用wgetorcurl代替命令行执行请求。

于 2014-01-09T20:34:43.397 回答