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

如何处理mod_wsgi/django中的阻塞IO?,django,apache,io,mod-wsgi,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) 如果我处理的http请求超过2个,并且正在处理此类IO

我在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)
如果我处理的http请求超过2个,并且正在处理此类IO,那么Django将只是阻塞,直到前面的一个请求完成

这是预期的行为吗?线程是否有助于缓解这种情况,即在看到这种等待之前,我是否应该能够为给定的WSGI进程处理多达15个单独的请求


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

如果处理是在python中,那么全局解释器锁不会被释放——在单个python进程中,一次只能执行一个python代码线程。不过,GIL通常是在C代码内部发布的——例如,与大多数I/O一样


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

+1对Radomir Dopieralski的回答


如果任务需要很长时间,您应该将其委托给请求-响应周期之外的进程,可以使用标准cron,也可以使用一些分布式任务队列(如用于工作负载卸载的数据库),这在2010年是个不错的主意,但现在我们已经走得更远了

我们使用ApacheKafka作为队列来存储飞行中的工作负载。因此,数据流现在是:

用户->apachehttpd->Kafka->python守护进程处理器

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

一组单独的python守护进程从Kafka中提取数据并对其进行处理。事实上,我们有多个需要以不同方式处理的过程,但卡夫卡通过只写一次并让多个读者在需要时读取相同的数据来加快处理速度;重复存储不会产生任何罚款

这允许非常非常快速的周转;最佳资源利用率,因为我们有其他框脱机处理来自卡夫卡的拉动,并且可以根据需要调整以减少延迟。Kafka是HA,相同的数据写入集群中的多个框中,因此我的经理不会抱怨“如果发生了什么”的情况


我们对卡夫卡很满意

嗯-不确定GIL是否适用于这种情况:我自己也不确定——数据库连接上可能有锁,或者长I/O也在做什么——例如sqlite3一次只允许一个写入程序。这一点可以更清楚。尽管由于GIL,一次只能运行一个线程中的Python代码,但运行Python代码的线程将控制另一个定期运行Python代码的线程。因此,您仍然可以有并发请求,但如果操作受CPU限制,那么GIL将限制您使用多个CPU的能力,因为一次只能运行一个Python代码线程,而不能跨多个CPU运行多个Python代码线程。绑定I/O的线程并不像“”中描述的那样是个大问题。此外,Apache在正常情况下不会终止进程。FASTCGI和mod_wsgi模块的一项功能通常是在请求时间过长时终止进程。对于mod_wsgi,强制关闭进程的能力只与守护进程模式有关,必须将其配置为非默认状态。它也不是严格的请求超时,而是作为非活动超时处理。也就是说,一个看起来不再消费或生产任何内容的流程。请参阅“”。