Python 异步编程框架的探索
异步编程在 Python 中如今占据了核心地位。对于 Web 开发人员来说,现在有许多杰出的框架可供选择!
在撰写本文时,异步不再仅仅是 Python 社区中的一个流行词。自从 Python 3.5 版本引入了 asyncio 库后,Python 承认了 Node.js 对 Web 开发的影响,并引入了两个新的关键字——async
和 await
。这是一个重要的里程碑,因为 Python 核心语法的扩展非常谨慎,除非有迫切的需求,这足以表明 Python 开发人员对异步功能的重视。
因此,异步编程的大门被打开了:新的和旧的库开始拥抱协程,异步框架开始流行,并且今天仍然有新的框架在不断涌现。 达到甚至超越 Node.js 的性能已不再罕见,除非你的负载包含大量的 CPU 密集型任务,否则每秒处理数千个请求是完全可行的。
那么,让我们深入了解一下 Python 的当前生态系统,并看看一些顶级的异步框架。
Tornado
出乎意料的是,Tornado 并不是一个新的框架。它的首次发布是在 2009 年(撰写本文时正好是十年前),从那时起,它的重点一直是提供具有高并发性的可靠的异步编程。
Tornado 本质上不是一个 Web 框架,而是一个异步模块的集合,它也被用来构建 Web 框架模块。更具体地说,这些模块包括:
- 协程和其他原语 (
tornado.gen
,tornado.locks
,tornado.queues
等) - 网络模块 (
tornado.ioloop
,tornado.iostream
等) - 异步服务器和客户端 (
tornado.httpserver
,tornado.httpclient
等)
这些模块被组合起来形成了最终的框架模块:tornado.web
, tornado.routing
, tornado.template
等。
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
def make_app():
return tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
Tornado 在 Python 社区中拥有强大而忠实的追随者,经验丰富的架构师使用它来构建高性能的系统。它是一个长期以来一直在解决并发问题的框架,但可能没有成为主流,因为它不支持 WSGI 标准,并且被许多人认为难以接受(记住,大部分 Python 库仍然是同步的)。
Sanic
Sanic 是一个真正意义上的“现代”框架:它不支持低于 3.6 的 Python 版本,并且直接支持简单的 async
/await
语法。因此,在编写你的第一个 HTTP 处理程序之前,你无需费力阅读大量文档和记住各种边缘情况。
其结果是,生成的语法非常简洁(至少在我看来);它类似于你使用任何其他微框架(如 Flask、CherryPy)编写的代码,只是添加了一些异步特性:
from sanic import Sanic
from sanic.response import json
app = Sanic()
@app.route("/")
async def test(request):
return json({"hello": "world"})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
Sanic 可以说是 Python 世界中最受欢迎和最受推崇的异步框架。它具有你项目所需的几乎所有功能——路由、中间件、cookie、版本控制、蓝图、基于类的视图、静态文件、流、套接字等。它没有开箱即用的功能(如模板、数据库支持、文件 I/O、队列)都可以通过丰富的异步库来实现。
Vibora
Vibora 是 Sanic 的近亲,但它的目标是成为目前最快的 Python Web 服务器。事实上,第一次访问它的网站时,你会看到一个框架比较:
正如你所见,Vibora 声称比传统框架快数倍,并且比其最直接的竞争对手 Sanic 快两倍以上。当然,对基准测试结果还是要持保留态度。🙂
尽管在语法和功能方面,Vibora 与 Sanic 可以相媲美(甚至可能略胜一筹,因为它捆绑了流行的库,并且开箱即用地提供模板等功能),但我认为 Sanic 更成熟,因为它存在的时间更长,并且拥有更大的社区。
from vibora import Vibora, JsonResponse
app = Vibora()
@app.route('/')
async def home():
return JsonResponse({'hello': 'world'})
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000)
不过,如果你是一个性能爱好者,Vibora 可能会让你满意。也就是说,在撰写本文时,Vibora 正在进行完全重写以变得更快,并且 相关文档 表明它正在“积极开发”性能版本。对于那些早期使用 Vibora 并且很快将面临重大变化的人来说,这可能会令人失望,但是,嘿,这是 Python 异步世界的早期阶段,没有人期望事情一成不变。
Quart
如果你喜欢使用 Flask 开发,但又对缺少异步支持感到遗憾,那么你一定会非常喜欢 Quart。
Quart 符合 ASGI 标准,该标准是著名的 WSGI 标准的继承者,并提供了异步支持。Quart 的有趣之处在于它不仅与 Flask 相似,而且实际上与 Flask API 兼容!该框架的作者希望保留 Flask 的感觉,只是添加了异步、WebSockets 和 HTTP/2 支持。因此,你可以直接从 Flask 文档中学习 Quart,只需记住 Quart 中的函数是异步的即可。
from quart import Quart
app = Quart(__name__)
@app.route('/')
async def hello():
return 'hello'
app.run()
感觉(几乎)和 Flask 完全一样,对吧?!
由于 Quart 是 Flask 的进化版,因此 Flask 内部的所有功能都可用:路由、中间件、会话、模板、蓝图等。事实上,你甚至可以直接在 Quart 中使用 Flask 扩展。一个问题是仅支持 Python 3.7+,但是,如果你没有运行最新版本的 Python,那么异步可能不是你的首选。 🙂
如果你没有使用 Flask 的经验,那么 Quart 的文档仍然需要改进。但我仍然推荐 Quart,因为它可能是唯一一个即将发布 1.0 版本的异步框架。
FastAPI
此列表中的最后一个(但也是最令人印象深刻的)框架是 FastAPI。不,它不是一个仅限 API 的框架;事实上,FastAPI 似乎是我在研究异步 Python 框架时遇到的功能最丰富、文档最完善的框架。
有趣的是,该框架的作者深入研究了其他几个框架,从像 Django 这样的传统框架到像 Sanic 这样的现代框架,以及跨技术研究 NestJS(一个 Node.js, Typescript Web 框架)。 你可以在 这里 阅读他们的开发理念和广泛的比较。
语法非常简洁;甚至可以说它比我们遇到的其他框架更有趣:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/me")
async def read_user_me():
return {"user_id": "the current user"}
@app.get("/users/{user_id}")
async def read_user(user_id: str):
return {"user_id": user_id}
现在,让 FastAPI 在其他框架中脱颖而出的关键特性列表如下:
自动生成 API 文档:一旦你编写了端点,你就可以使用符合标准的 UI 来使用 API。支持 SwaggerUI、ReDoc 等。
该框架还使用 JSON Schema 自动生成数据模型文档。
现代开发:是的,“现代”这个词经常被提及,但我发现 FastAPI 实际上做到了名副其实。依赖注入和类型提示是一等公民,不仅遵循了良好的编码原则,而且从长远来看可以防止错误和混乱。
广泛的文档:我不了解你,但我完全是一个好文档的粉丝。在这一方面,FastAPI 毫无疑问地胜出。它有无数页的文档解释了几乎每一个小细节和各个级别开发人员需要“注意!”的细节。我在文档中感受到了一种清晰的“心和灵魂”,我能找到的唯一可与之媲美的只有 Django 的文档(是的,FastAPI 的文档就是这么好!)。
超越基础:FastAPI 支持 WebSockets、Streaming 和 GraphQL,此外还有 CORS、会话、cookie 等所有传统助手。
那么性能呢?好吧,FastAPI 是建立在令人惊叹的 Starlette 库之上的,它的性能可以与 Node 相媲美,在某些情况下甚至可以与 Go 相媲美!总而言之,我真的觉得 FastAPI 将成为 Python 的顶级异步框架。
结论
这些天来,Python 的异步领域正在发生很多事情。新框架不断涌现,旧框架正在被重写,库正在进化以适应异步行为。虽然 Python 具有对事件循环的内置支持,并且可以使应用程序的某些部分异步,但你也可以选择全力以赴,并使用此处列出的其中一个框架。 请务必牢记长期影响:一些 Python 异步框架仍处于早期阶段,并且正在快速发展,这可能会损害你的开发过程并提高业务成本。谨慎是关键!
但无论如何,当涉及到 Web 框架时,Python 已经准备好为生产环境提供卓越的性能。 如果你长期以来一直在考虑迁移到 Node,那么现在你不需要这样做了! 🙂
听起来很棒吗? 今天就掌握 Python!