Django 异步处理
我有一堆Django请求,这些请求会执行一些数学计算(这些计算是用C语言写的,通过Cython模块来执行),可能需要不确定的时间(大约1秒左右)来完成。而且这些请求不需要访问数据库,彼此之间也没有依赖关系,也不依赖于Django。
目前一切都是同步的(使用Gunicorn和sync
工作类型),但我想把它改成异步的,不要阻塞。简单来说,我想做以下几件事:
- 接收AJAX请求
- 把任务分配给一个可用的工作者(不阻塞主Django网页应用)
- 工作者在某个未知的时间内执行任务
- 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的结合更加顺畅。
如果你需要更具体的建议,请留言。