WSGI与ASGI:两种Python Web服务器网关接口的比较
在当今的Web开发领域,选择合适的服务器网关接口(Server Gateway Interface,简称SGI)对于提高Web应用程序的性能和并发性至关重要。在Python中,有两种常见的SGI:WSGI
和ASGI
。本文将深入探讨这两种SGI的异同点。
1、WSGI的概念
首先,让我们了解一下WSGI(Web Server Gateway Interface)。
WSGI
是一种同步的网关接口,它使用线程来处理每个请求,通过简单的函数调用——一个可调用的对象(通常是一个函数)来处理HTTP请求,并返回HTTP响应。这意味着在一个请求被处理期间,其他请求必须等待。这种同步处理方式在处理大量并发请求时可能会导致性能问题,因此WSGI适用于处理低并发、IO密集型的应用程序,在这种环境下,同步的请求处理足够高效。由于这种限制,WSGI的典型实现包括Gunicorn、uWSGI和mod_wsgi等。
2、ASGI的概念
随着异步编程概念的普及,出现了另一种网关接口——ASGI(Asynchronous Server Gateway Interface)。
ASGI
是一种异步的网关接口,允许同时处理多个请求。通过使用事件循环和协程,ASGI
可以实现高并发性能,从而更好地应对大量并发请求。ASGI
的典型实现包括Daphne
、Uvicorn
和 Hypercorn
等。
3、请求方式差异
通过上面的概念,我们了解到WSGI和ASGI在请求方面的差异,主要体现在同步和异步处理请求上。通过一个简单的例子来进一步理解WSGI和ASGI之间的区别。
假设我们有一个名为"my_web_app"
的Python Web
应用程序,它需要连接到Web服务器并处理来自客户端的请求。我们可以使用WSGI
或ASGI
来实现这个连接。
3.1、使用 WSGI
的例子:
from wsgiref.simple_server import make_server def application(environ, start_response): status = '200 OK' headers = [('Content-type', 'text/plain')] start_response(status, headers) return [b"Hello World"] httpd = make_server('', 8000, application) print("Serving on port 8000...") httpd.serve_forever()
在上面的例子中,我们使用 WSGI
的典型实现之一——make_server
函数来创建了一个简单的 Web
服务器。我们直接访问 localhost:8000
, 可以看到浏览器显示 Hello World
字样。
这个函数接受三个参数:请求处理函数、服务器的地址和端口号。当客户端发送请求时,服务器将调用请求处理函数,并将请求的详细信息传递给它。请求处理函数可以返回一个响应,服务器将将其发送回客户端。
3.2、使用 ASGI
的例子
from asgiref.sync import async_to_sync from daphne import Daphne from http import HTTPStatus import HTTPStatus from channels.layers import get_channel_layer from channels.routing import ProtocolTypeRouter, URLRouter from django.core.asgi import get_asgi_application import os import sys import asyncio channel_layer = get_channel_layer() asgi_app = get_asgi_application() async def application(scope, receive, send): if scope['type'] == 'http': await asgi_app(scope, receive, send) elif scope['type'] == 'websocket': await async_to_sync(channel_layer)(scope, receive, send) else: raise Exception('Unknown scope type')
在上面的例子中,我们使用 ASGI
的典型实现之一——Daphne
来创建了一个异步的Web服务器。Daphne
是一个ASGI服务器,它能够同时处理HTTP和WebSocket连接。在应用程序中,我们首先获取了一个channel layer对象和一个ASGI应用程序对象。然后,我们定义了一个异步的请求处理函数,它根据请求的类型选择使用ASGI应用程序或channel layer来处理请求。对于HTTP请求,我们直接调用ASGI应用程序;对于WebSocket请求,我们使用channel layer来处理。最后,我们将请求处理函数传递给Daphne服务器,让它来处理来自客户端的请求。
通过这个例子,我们可以看到WSGI和ASGI的主要区别在于它们处理请求的方式和性能。WSGI使用同步的方式处理请求,每个请求都需要在一个单独的线程中执行。而ASGI使用异步的方式处理请求,可以同时处理多个请求,并通过事件循环和协程实现高并发性能。因此,选择使用WSGI还是ASGI取决于你的应用程序的具体需求和性能要求。
上一篇文章:Python如何实现查看WiFi密码?
4、支持协议差异
除了处理请求的方式不同,WSGI和ASGI在支持的协议方面也存在差异。 WSGI是基于HTTP协议模式开发的,不支持WebSocket。这意味着使用WSGI的应用程序无法直接处理WebSocket连接,需要借助其他库或中间件来实现。
相比之下,ASGI不仅支持现有的Web开发中的一些新的协议标准,还支持原有模式和WebSocket的扩展。这使得使用ASGI的应用程序可以更灵活地适应不断变化的Web技术。
5、总结
总之,WSGI和ASGI在处理请求、性能、支持的协议和典型实现等方面存在差异,选择哪种网关接口取决于具体情况。
如果你的应用程序需要处理高并发请求并且希望利用异步编程的优势,那么ASGI是一个更好的选择。然而,如果你的应用程序更关注与现有技术的兼容性并且不需要处理大量并发请求,那么WSGI可能是一个更合适的选择。
随着异步编程的日益普及和Web技术的不断发展,预期ASGI将在未来的Python Web开发中发挥越来越重要的作用。然而,WSGI作为传统的网关接口,仍将在许多现有的应用程序中发挥关键作用。 了解这两种SGI的优缺点有助于我们在构建和优化Web应用程序时做出明智的决策。
如果你觉得文章还不错,记得关注公众号: 锅外的大佬 锅外的大佬博客

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
实例讲解数据库的数据去重
本文分享自华为云社区《GaussDB数据库SQL系列-数据去重》,作者: Gauss松鼠会小助手2 。 一、前言 数据去重在数据库中是比较常见的操作。复杂的业务场景、多业务线的数据来源等等,都会带来重复数据的存储。本文以GaussDB数据库为实验平台,将为大家详细讲解如何去重。 二、数据去重应用场景 •数据库管理(含备份):在数据库中进行数据去重可以避免数据重复存储、备份,提高数据库的存储效率、降低备份的存储成本。 •数据集成:在数据集成的过程中,需要合并多个数据源的数据,去重可以避免重复的数据对合并结果的影响。 •数据分析(或挖掘):在进行数据分析或数据挖掘时,去重可以避免重复的数据对分析或挖掘结果的干扰,提高分析的准确性。 •电商平台:在电商平台上进行商品去重可以避免重复上架相同的商品,提高平台的用户体验。 •金融风控:在金融风控领域,去重可以避免重复的数据对风控模型的影响,提高风控的准确性。 三、数据去重案例(GaussDB) 实战业务场景 + GaussDB数据库 1、示例场景描述 以保险行业的客户信息除重为例,为防止坐席重复联系客户(容易造成客户投诉),需要将客户进行唯一身份...
- 下一篇
盘点 MySQL 创建内部临时表的所有场景
作者总结了 MySQL 中所有触发使用内部临时表的场景。 作者:刘嘉浩,爱可生团队 DBA 成员,重度竞技游戏爱好者。 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。 本文约 2000 字,预计阅读需要 5 分钟。 临时表属于是一种临时存放数据的表,这类表在会话结束时会被自动清理掉,但在 MySQL 中存在两种临时表,一种是外部临时表,另外一种是内部临时表。 外部临时表指的是用户使用 CREATE TEMPORARY TABLE 手动创建的临时表。而内部临时表用户是无法控制的,并不能像外部临时表一样使用 CREATE 语句创建,MySQL 的优化器会自动选择是否使用内部临时表。 那么由此引发一个问题,MySQL 到底在什么时候会使用内部临时表呢? 我们将针对 UNION、GROUP BY 等场景进行分析。 UNION 场景 首先准备一个测试表。 CREATETABLE`employees` ( `id`intNOTNULLAUTO_INCREMENT, `first_name`varchar(100)COLLATEutf8mb4_binDEFAULTNUL...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Mario游戏-低调大师作品
- CentOS8编译安装MySQL8.0.19
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS6,7,8上安装Nginx,支持https2.0的开启