当前位置: 首页 > 科技观察

ASGI详解:PythonWeb开发的未来_0

时间:2023-03-12 21:20:25 科技观察

译者|李睿评论|SunShujuanPythonWeb应用程序长期以来一直遵循Web服务器网关接口(WSGI)标准,该标准描述了它们如何与Web服务器通信。WSGI最初于2003年推出并于2010年更新,它仅依赖于Python2.2中本机可用的易于实现的功能。因此,WSGI很快被纳入所有主要的PythonWeb框架,成为PythonWeb开发的基石。快进到2022年。Python2已经过时,Python现在具有处理网络调用等异步操作的本机语法。WSGI和其他默认采用同步行为的标准无法利用异步的性能和效率增益。这反过来意味着WSGI无法有效地处理更高级别的协议,如WebSocket。输入ASGI,异步服务器网关接口。与WSGI类似,ASGI描述了PythonWeb应用程序和Web服务器之间的通用接口。与WSGI不同,ASGI允许每个应用程序有多个异步事件。此外,ASGI同时支持同步和异步应用程序。开发人员可以将遗留的同步WSGIWeb应用程序迁移到ASGI,或者使用ASGI构建新的异步Web应用程序。1.WSGI的工作原理WSGI的工作原理是将Python函数暴露给Web服务器,通常称为应用程序或应用程序。该函数有两个参数:environ:一个字典,包含有关当前请求和Web服务器提供的环境变量的信息。start_response:将用于启动将HTTP响应发送回客户端的函数。函数返回的数据构成响应主体。一个简单的应用程序函数可能如下所示:defapplication(environ,start_response):start_response('200OK',[('Content-Type','text/plain')])return[b'Greetingsuniverse']If如果你使用的是兼容WSGI的web框架(比如Flask),那么框架本身会提供一个应用功能,它的所有组件都会自动连接起来。WSGI有两个缺点:首先,WSGI一次只处理一个请求和响应,并假定响应会立即返回。没有办法处理长时间保持的连接,例如WebSocket或长轮询HTTP连接。其次,WSGI只是同步的。即使使用多线程连接池,每个连接也会阻塞,直到它返回响应。许多WSGI设置能够处理线程池和进程池,但这些受限于WSGI接口本身的同步。2.ASGI的工作原理ASGI在外观上与WSGI相似。和WSGI一样,开发者可以定义一个应用程序函数对象,但它是一个异步函数,有三个参数而不是两个:scope:包含当前请求信息的字典,类似于WSGI中的environ,但细节的命名约定略有不同.发送:一个异步可调用对象,允许应用程序将消息发送回客户端。receive:一个异步可调用对象,允许应用程序从客户端接收消息。一个简单的ASGI应用程序函数如下所示:asyncdefapplication(scope,receive,send):awaitsend({'type':'http.response.start','status':200,'headers':[[b'content-type',b'text/plain'],],})awaitsend({'type':'http.response.body','body':b'Hello,world!',})和LiketheWSGIweb框架,ASGIweb框架将生成自己的application()函数并根据需要将其连接起来。与ASGI最明显的区别是在整个函数中使用了异步隐喻。该函数本身是异步的,其中HTTP标头和响应文本在两个单独的awaitsend()命令中发送。这样,函数本身及其发送命令不会阻塞任何东西;它们可以与应用程序的调用交织在一起,并同时从许多其他连接发送。本例中没有使用receive,但也是一个异步函数。它可以在不阻止其他操作的情况下接收请求文本。请求和响应可以通过这种方式递增地传入和传出服务器——这是WSGI做不到的,或者根本做不到的。3、在ASGI中使用同步和异步函数在使用ASGI时,需要尽可能多地使用异步函数和异步友好库。养成使用异步的习惯是值得的,因为使用仅同步代码的问题可能很严重。对同步函数的任何长时间调用都会阻塞整个调用链,从而使使用异步的好处几乎被抹杀。如果您在使用长时间运行的同步调用时遇到问题,则需要使用asyncio.run_in_executor将调用外包给线程池或进程池。每当等待外部事件或非CPU密集型任务时,都应使用线程池。而进程池应该用于CPU密集型本地任务。例如,如果Web应用程序中有调用远程网站的路由,则应使用线程。或者更好的是,使用发出异步HTTP请求的aiohttp库。如果你想调用Pillow图像库来调整图像大小,你应该使用带有进程池的run_in_executor。尽管在进程之间来回传输数据会产生一些轻微的开销,但使用run_in_executor不会阻塞其他事件。4、支持ASGI的Web框架可以通过实现application()对象手动编写ASGIWeb应用。但在绝大多数情况下,使用异步原生、以ASGI为中心的PythonWeb框架会更简单。以下是一些常见的ASGI兼容Web框架:Starlette和FastAPI:这些新兴框架(FastAPI建立在Starlette之上)都是异步优先的,因此它们都支持ASGI也就不足为奇了。如果您从头开始开发Web应用程序,它们是Python最现代和最前沿的Web框架。Quart:虽然主要的PythonWeb框架Flask确实支持ASGI,但Flask并不是为了从内到外利用异步隐喻而设计的。GitLab的Quart使用Flask的语法和隐喻,但允许异步路由处理程序。Django3.0及以上版本:从Django3.0开始,久负盛名的Djangoweb框架支持ASGI。在Django3.1中添加了对Django应用程序中异步代码的支持,而不仅仅是能够将Django安装在ASGI处理程序上。对于一个不以执行速度着称的框架,异步的存在会为那些选择利用它的人带来更好的性能。原文链接:https://img.ydisp.cn/news/20220914/uottbcmzxro