在 django view 中使用 asyncio 去调用十次外部 api,经过测试确实比同步请求快,但是搜索 django asyncio 相关问题时,发现有人说:在 django view 中使用 asyncio,会阻塞整个 django worker,这一点有些不能理解,有人能解释一下吗,如果不使用异步请求,用 celery 的 group 去做,这两者有什么区别?
问题来源: https://stackoverflow.com/questions/44667242/python-asyncio-in-django-view#comment88445130_44683173
1
so1n 2019-04-01 00:24:37 +08:00
django 是同步的啊,自己本来的 request/response 周期也就是同步的(也就是一个 view )。如果你这个周期里面有十个外部 API 请求,那这个周期的时间能减少,但没有办法做到先返回响应,再去异步请求,可以使用 Django channel 来让 view 异步
|
2
welkinzh OP @so1n 如果这个 view 的过程就是请求这些 api,然后处理返回的结果最后响应,那使用 asyncio 是不是就达到了减少响应时间这个目的呢,这样看的话,和使用 celery 的效果是一样的,我的理解对吗
|
3
welkinzh OP 我想我可能理解错那条评论的意思了,run_until_complete 会阻塞当前请求,而不会影响其他请求。贴上评论
@Juanvulcano it works faster because you run async requests concurrently. However, loop.run_until_complete(main(language1, language2)) blocks further execution until async actions are complete. That means django worker won't be able to serve other requests till this one is complete. |
7
neoblackcap 2019-04-01 07:22:03 +08:00 2
@welkinzh 可以的,你的用法是正确的。你的使用相当于收集了好几个远程 API 的结果。不过嘛,一般我们不会这样使用 asyncio。如果你的处理牵涉到大量的网络请求,我建议你使用 Tornado 之类的框架进行网络 IO 重写,让 Tornado/asyncio 负责处理网络 IO,Django 这边就单纯地使用一个 requests 去请求 Tornado/asyncio 暴露出来的 API 就好了。
|
8
Qzier 2019-04-01 11:07:57 +08:00
loop.run_until_complete() 是同步代码,当然会阻塞,再说了 Django 本来就是同步框架,如果你不想阻塞,要么用再开一个线程,要么把任务交给 Celery。
|