如何在mod_wsgi / django中处理阻塞IO?

时间:2010-08-23 20:22:14

标签: django apache io mod-wsgi

我使用以下配置在守护进程模式下运行Apache + mod_wsgi下的Django:

WSGIDaemonProcess myserver processes=2 threads=15

我的应用程序在后端执行了一些IO,这可能需要几秒钟。

def my_django_view:
    content=... # Do some processing on backend file
    return HttpResponse(content)

看来,如果我正在处理超过2个处理这种IO的​​http请求,Django将直接阻塞,直到之前的一个请求完成。

这是预期的行为吗?在我看到这种等待之前,不应该使用线程帮助减轻这一点,即我不应该为给定的WSGI进程处理多达15个单独的请求吗?

或者我在这里遗漏了什么?

3 个答案:

答案 0 :(得分:2)

如果处理是在python中,则不会释放Global Interpreter Lock - 在单个python进程中,一次只能执行一个python代码线程。 GIL通常在C代码中发布 - 例如,像大多数I / O一样。

如果这种处理会发生很多,你可以考虑运行第二个“工人”应用程序作为守护程序,从数据库中读取任务,执行操作并将结果写回数据库。 Apache可能会决定终止需要很长时间才能响应的进程。

答案 1 :(得分:2)

+1给Radomir Dopieralski的答案。

如果任务需要很长时间,您应该通过使用标准cron或某个分布式任务队列(如Celery

)将其委托给请求 - 响应周期之外的进程。

答案 2 :(得分:0)

工作负载卸载的数据库在2010年是相当的事情,然后是一个好主意,但我们现在已经走得更远了。

我们将Apache Kafka用作存储我们的飞行中工作负载的队列。所以,Dataflow现在是:

用户 - > Apache httpd - >卡夫卡 - > python守护程序处理器

用户发布操作将数据放入系统以通过wsgi app进行处理,该应用程序只是将其快速写入Kafka队列。在后期操作中进行最小的健全性检查以保持其快速但发现一些明显的问题。 Kafka非常快速地存储数据,因此http响应非常快。

一组单独的python守护进程从Kafka中提取数据并对其进行处理。我们实际上有多个进程需要以不同的方式处理它,但是Kafka通过只编写一次并让多个读者在需要时读取相同的数据来实现快速;不会因重复存储而受到处罚。

这允许非常非常快速的周转;最佳资源使用,因为我们有其他盒子离线处理pull-from-kafka并且可以根据需要调整它以减少延迟。 Kafka是HA,它将相同的数据写入群集中的多个框,因此我的经理不会抱怨如果'会发生什么?场景。

我们对卡夫卡非常满意。 http://kafka.apache.org