Django中的线程在生产中不起作用

Posted

技术标签:

【中文标题】Django中的线程在生产中不起作用【英文标题】:Threading in Django is not working in production 【发布时间】:2017-10-22 22:06:36 【问题描述】:

我的 Django views.py 中有一个看起来像这样的函数。

def process(request):
form = ProcessForm(request.POST, request.FILES)
if form.is_valid():
    instance = form.save(commit=False)
    instance.requested_by = request.user
    instance.save()
    t = threading.Thread(target=utils.background_match, args=(instance,), kwargs=)
    t.setDaemon(True)
    t.start()
    return HttpResponseRedirect(reverse('mart:processing'))

在这里,我尝试在提交 ProcessForm 时在单独的线程中调用函数“background_match”。由于这个线程需要一些时间才能完成,我将用户重定向到另一个名为“mart:processing”的页面。

我面临的问题是它在我的本地机器上一切正常,但在作为 AWS EC2 实例的生产服务器上不起作用。线程根本没有启动。 background_match 函数内部有一个 for 循环,它不会向前移动。

但是,如果我刷新 (CTRL + R) 'mart:processing' 页面,它会移动 1 或 2 次迭代。因此,要运行一个包含 1000 次迭代的完整循环,我需要刷新页面 1000 次。如果在 100 次迭代之后我不刷新页面,它会卡在那个点并且不会移动到第 101 次迭代。请帮忙!

【问题讨论】:

你是在生产中使用uwsgi,在本地运行服务器吗? 【参考方案1】:

错误的架构。 Django 和其他网络应用程序应该像这样产生线程。正确的方法是使用任务队列创建异步任务。 django 最受欢迎的任务队列恰好是Celery。

mart:processing 页面随后应检查异步结果以确定任务是否已完成。粗略的草图如下。

from celery.result import AsynResult
from myapp.tasks import my_task

...
if form.is_valid():
    ...
    task_id = my_task()
    request.session['task_id']=task_id
    return HttpResponseRedirect(reverse('mart:processing'))
    ...

在下一页

task_id = request.session.get('task_id')
if task_id:
    task = AsyncResult(task_id)

【讨论】:

如何在mart:processing页面查看异步结果? 查看更新,但您需要在继续之前完整阅读该页面 如果它是一个错误的架构那么为什么它在我的本地机器上工作得很好> Pallav,您的本地计算机可能正在运行与生产服务器不同的开发服务器。无论如何,你不必相信我的话。这里有很多问题,人们走这条路并苦苦挣扎 好的,如果在同一个会话中创建多个任务,这会起作用吗?

以上是关于Django中的线程在生产中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

在 Docker 上运行时,Spring Boot 上传功能在生产中不起作用

Tailwind 自定义背景图像在生产中不起作用

SMTP 配置在生产中不起作用

谷歌推送通知在生产中不起作用

iOS推送通知在生产中不起作用

Flutter Firebase Google Auth 在生产中不起作用