在Django Web应用程序中运行异步python代码

时间:2015-01-26 05:07:01

标签: python django asynchronous

在Django Web应用程序中异步运行某些代码片段是否可以。如果是这样的话?

例如:

我有一个搜索算法,可以返回数百或数千个结果。我想进入数据库,这些项目是搜索的结果,所以我可以看到用户最常搜索的内容。我不希望客户端等待额外的数百或数千个数据库插入。有没有办法可以异步执行此操作?这样做有危险吗?有没有更好的方法来实现这一目标?

2 个答案:

答案 0 :(得分:3)

就Django而言,是的。

更大的问题是你的网络服务器,如果它与线程很好。例如,gunicorn的同步工作者是单线程,但还有其他引擎,例如greenlet。我不确定他们玩线程有多好。

如果您从线程分离,则组合线程和多处理可能是一个问题:

Status of mixing multiprocessing and threading in Python

http://bugs.python.org/issue6721

话虽如此,我知道流行的性能分析实用程序已经使用线程来报告指标,因此似乎是一种公认​​的做法。

总而言之,使用标准库中的threading.Thread对象似乎最安全,只要你在其中做的任何事情都不会fork(python的多处理库)

https://docs.python.org/2/library/threading.html

答案 1 :(得分:2)

从主线程卸载请求是一种常见做法;最终目标是尽快将结果返回给客户端(浏览器)。

我确信您已经知道,HTTP正在阻止 - 所以在您返回响应之前,客户端无法执行任何操作(它处于阻塞状态,处于等待状态)。

卸载请求的事​​实上的方法是通过celery这是一个任务排队系统。

我强烈建议您阅读introduction to celery主题,但总结如下:

  1. 您将某些代码标记为“任务”。这些通常是您想要异步运行的函数。

  2. Celery管理员工 - 您可以将其视为线程 - 将执行这些任务。

  3. 要与工作人员通信,需要消息队列RabbitMQ是经常推荐的。

  4. 一旦你运行了所有组件(只需几分钟);你的工作流程是这样的:

    1. 在你看来,当你想卸下一些工作时;您将使用.delay()选项调用使用该函数的函数。这将触发工作人员在后台开始执行该方法。

    2. 您的视图会立即返回响应。

    3. 然后,您可以检查任务的结果,并根据需要执行的操作采取适当的操作。还有ways to track progress

    4. 包含缓存也是一种很好的做法 - 这样您就不会不必要地执行昂贵的任务。例如,您可以选择卸载请求,对将放置在报告中的搜索关键字进行一些分析。

      生成报告后,我会缓存结果(如果适用),以便稍后请求显示相同的报告 - 而不是再次生成。