Django 3.x-哪个ASGI服务器(Uvicorn vs.Daphne)

Django 3.x-哪个ASGI服务器(Uvicorn vs.Daphne),django,daphne,asgi,uvicorn,Django,Daphne,Asgi,Uvicorn,我用Django3编写了一个简单的基于API的web应用程序。在Django文档中,有一个关于服务器的示例,其中提到了两个选项:和。不幸的是,它们没有提供任何关于某个特定选择的好处的描述,所以当选择其中一个时,我感到困惑 围绕这两者编写Django应用程序有什么区别(如果有的话),是否有任何性能或稳定性问题需要注意 基本上,用乌维康代替达芙妮有很大区别吗?我的服务器运行在Ubuntu上,如果有必要的话。简单回答: 因为您以前使用过gunicorn,而且您对它很熟悉,所以请使用uvicorn,特别

我用Django3编写了一个简单的基于API的web应用程序。在Django文档中,有一个关于服务器的示例,其中提到了两个选项:和。不幸的是,它们没有提供任何关于某个特定选择的好处的描述,所以当选择其中一个时,我感到困惑

围绕这两者编写Django应用程序有什么区别(如果有的话),是否有任何性能或稳定性问题需要注意


基本上,用乌维康代替达芙妮有很大区别吗?我的服务器运行在Ubuntu上,如果有必要的话。

简单回答: 因为您以前使用过gunicorn,而且您对它很熟悉,所以请使用uvicorn,特别是因为它应该作为一种工具使用。 如果您没有这方面的经验,那么我建议您使用达芙妮。 两者都将在一个简单的项目上完成工作,而且性能似乎是相同的


说明:

ASGI是一项相当新的技术,与语言中大多数其他改变设计的元素相比,python的async/await也是如此。 uvicorn、daphne和hypercorn也在积极开发中,因此这些库不可能有任何“公平”的基准测试。所以,当你选择你想要的东西时,你通常不得不接受他们的话,比如说他们说的话;它们的目标是速度快、使用简单、重量轻或其他任何东西

尽管如此,我仍然可以分享我与乌维康和达芙妮的经历:

Daphne无疑是一个庞大的项目,它有很多依赖项,但并不是每个项目都完全使用这些依赖项。他们已经尽了最大努力覆盖了很多特性,而且因为他们也是Django团队的一部分,所以您应该期望与Django有更好的长期兼容性。不过,与达芙妮开始接触可能会让人胆战心惊

Uvicorn是一款轻量级的,您甚至可以阅读整个库的代码,并了解齿轮是如何在内部转动的。因为我主要使用的是Uvicorn,所以我知道它缺少一些功能和bug,而如果您希望从ASGI服务器获得自定义行为,那么篡改Uvicorn比其他方法更容易。关于Uvicorn,我最喜欢的部分是,它甚至不是一个流程管理器,它被设计成gunicorn的生产工人

旁注:挂入Uvicorn实际上不是有意的,也不容易。 这样做通常不是很好的做法,但考虑到在搜索了18个小时的替代方案后(我个人希望捕获并处理SIGTERM以实现优雅的关机,但由于所有内容都在异步循环中,所以常规方法无法工作),我找不到任何更好的方法。因此,我将无耻地放一段代码,它将授予您难以捉摸的“服务器”实例。从那里,仔细地穿线。(没有双关语)

另一个旁注:
如果您真的选择使用Uvicorn,并且您正在使用django和频道,那么您可能需要先删除“daphne”,因为它是一个频道的集合。

为什么要使用ASGI服务器?您是否在任何地方使用异步代码?@TomCarrick我想开始在某些部分使用,主要是尝试通过数据处理来加速某些操作。我还认为,当我将gunicorn换成其他东西时,这可能会影响服务器的整体性能,因为它提供了一个在Django中使用async的框架。我有一些长期运行的工作,我想把WebSocket放在前面。我们看到的一种模式是,使用一个单独的异步套接字服务器将消息放入代理,然后由Django服务订阅。渠道是乌维康vs达芙妮的原因之一。对于常规Django应用程序的异步协同路由性能,而不是通过利用eventlet或gevent实现线程。
Hypercorn
现在也提到了。我需要说的是,我正在尝试使开发环境和登台/生产尽可能相似。所以我也在发展中使用达芙妮。到目前为止没有问题。。。但它不支持autoreload和。hypercorn和uvicorn都支持。好吧,我应该进一步补充一点,hypercorn支持HTTP2,uvicorn目前不支持(2021年4月)。
import inspect #Might not be future proof! Use with care
from uvicorn import Server as UvicornServer
server = next( server for frameinf in inspect.stack() if 'server' in frameinf[0].f_locals and isinstance(server:=frameinf[0].f_locals['server'], UvicornServer) )