如何在Django中使用uvicorn和ASGI的力量?

4
我实现了一个小型的 Django 应用程序(v4.0.4),其中包含一个 REST API - 用于检索一些数据的 GET 方法。接下来,我想使用 gunicorn+uvicorn 运行该项目,因为我在一篇文章中看到了比普通部署更好的基准性能。所以,我决定使用 wrk 工具来获取自己的基准测试结果。

这是我的测试结果:

命令 Web服务器 协议 结果 (Req/Sec)
python manage.py runserver 0.0.0.0:8000 Django 默认 wsgi 13.06
gunicorn bitpin.wsgi:application --bind 0.0.0.0:8000 -w 2 gunicorn wsgi 45.20
gunicorn bitpin.asgi:application --bind 0.0.0.0:8000 -w 2 -k uvicorn.workers.UvicornWorker uvicorn+gunicorn asgi 22.17

然而,上面的结果显示了另外一件事情!
是否原因是我想要使用 asgi,所以我必须为我的 API 视图使用 async 方法?如果是这样,我该如何将 Django REST API 视图更改为异步视图? 或者,我可能错过了某些配置?


[注意]:

  • I ran the benchmark using the following command:

    wrk -t4 -c11 -d20s -H "Authorization: Token xxx" http://127.0.0.1:8000/api/v1/content/
    
  • It is worth mentioning that for this test I used two workers for gunicorn and it is obvious that the higher workers, the better the performance will be.


1
如果您在启用了HPA(水平自动缩放)的Kubernetes环境中作为微服务运行,则使用Django默认服务器即可。Kubernetes将根据负载保持自动缩放(向上或向下),它将添加或减少Pod(例如更多的uvicorn工作进程),这将是动态的。Gunicorn / uvicorn工作进程数量在启动时固定,无法在运行时更改。您可能正在谈论物理服务器,但我认为如果其他人面临这种困境,我会在此处留下我的答案。 - Gajendra D Ambi
1个回答

2
如果您想创建异步 REST API,可以使用一个异步主函数,并从该函数调用另一个同步函数。例如:
#url.py:
path('Create',views.data_export,name='export_database')

#view.py

async def data_export(request):
  if(request.method == 'POST'):
    if(db_connect):
      system_id=request.POST.get('system_id')
      export_id =request.POST.get('export_id')  
      asyncio.create_task(start(system_id,export_id))

  return HttpResponse("Starting")

async def start(system_id,export_id):
  export_task = sync_to_async(start_export,thread_sensitive=False)
  system_id=str(config['COLLECTION_NAME']+'_'+system_id)
  await export_task(system_id,export_id)

export_task是一个同步函数。

以下是我如何将rest api变成异步的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接