Django 异步处理

8 投票
2 回答
10206 浏览
提问于 2025-04-16 09:04

我有一堆Django请求,这些请求会执行一些数学计算(这些计算是用C语言写的,通过Cython模块来执行),可能需要不确定的时间(大约1秒左右)来完成。而且这些请求不需要访问数据库,彼此之间也没有依赖关系,也不依赖于Django。

目前一切都是同步的(使用Gunicorn和sync工作类型),但我想把它改成异步的,不要阻塞。简单来说,我想做以下几件事:

  1. 接收AJAX请求
  2. 把任务分配给一个可用的工作者(不阻塞主Django网页应用)
  3. 工作者在某个未知的时间内执行任务
  4. Django在任务完成时返回计算结果(一个字符串列表),以JSON格式发送

我对异步Django还很陌生,所以我想问一下,做这个的最佳技术栈是什么。

这种流程是否适合用任务队列来处理?有人推荐使用Tornado + Celery + RabbitMQ,还是其他的方案呢?

提前谢谢大家!

2 个回答

0

因为你打算让它变成异步的(可能会用到像gevent这样的工具),你也可以考虑为计算工作建立一个多线程或分叉的后端网络服务。

异步的前端服务器可以处理所有轻量级的工作,比如从适合异步操作的数据库(像redis或者使用特殊驱动的mysql)获取数据等等。当需要进行计算时,前端服务器可以把所有输入数据发送到后端服务器,并在后端服务器完成计算后获取结果。

由于前端服务器是异步的,它在等待结果的时候不会被阻塞。这和使用celery相比的好处是,你可以在结果一出来就立刻把它返回给客户端。

client browser <> async frontend server <> backend server for computations
14

Celery非常适合这个需求。

因为你要做的事情相对简单(也就是说,你不需要复杂的任务分配规则),所以你可以选择使用Redis作为后端,这样就不需要设置和配置RabbitMQ了(根据我的经验,RabbitMQ的设置会更麻烦)。

我在开发版本的Celery中使用Redis,以下是我配置中的相关部分:

# Use redis as a queue
BROKER_BACKEND = "kombu.transport.pyredis.Transport"
BROKER_HOST = "localhost"
BROKER_PORT = 6379
BROKER_VHOST = "0"

# Store results in redis
CELERY_RESULT_BACKEND = "redis"
REDIS_HOST = "localhost"
REDIS_PORT = 6379
REDIS_DB = "0"

我还在使用django-celery,这样可以让它和Django的结合更加顺畅。

如果你需要更具体的建议,请留言。

撰写回答