整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

uvicorn,一个高效的 ASGI 服务器!

大家好,我是橙子!今天我们来聊聊 uvicorn,这个在 Python 网络编程中非常高效且受欢迎的 ASGI 服务器。如果你在构建 Python Web 应用,尤其是想要提升性能,或是开发高并发系统,那么 uvicorn 会是一个非常合适的选择。

在今天的教程中,我们将一起探讨:

什么是 ASGI,为什么需要 uvicorn?

如何安装和配置 uvicorn 服务器

如何用 uvicorn 启动一个简单的 Web 应用

如何在生产环境中优化 uvicorn 服务器的性能

让我们从头开始,轻松搞定 uvicorn 的安装与使用!

什么是 ASGI,为什么需要 uvicorn?

在了解 uvicorn 之前,首先要知道 ASGI( Server Gateway )是干什么的。简单来说,ASGI 是 Python Web 应用的接口规范,它为 Python 提供了更灵活的异步编程支持,相较于传统的 WSGI(Web Server Gateway ),ASGI 支持更高效的异步 I/O 操作,特别适合实时性要求较高的应用,如聊天系统、实时数据推送等。

而 uvicorn 是一个 ASGI 服务器,也就是说,它是一个高效、快速的 Web 服务器,专门用来处理符合 ASGI 规范的 Python Web 应用。与传统的 WSGI 服务器(比如 )相比,uvicorn 在处理并发和异步任务时表现得更加优异。

安装 uvicorn

要开始使用 uvicorn,首先需要在 Python 环境中安装它。打开命令行,输入以下命令进行安装:

pip install uvicorn

小贴士:

pip install "uvicorn[gunicorn]"

使用 uvicorn 启动一个简单的 Web 应用

接下来,我们用 uvicorn 启动一个简单的 FastAPI 应用(FastAPI 是一个高性能的 Web 框架,专为 ASGI 设计)。我们将通过一个简单的 "Hello World" API 来了解如何使用 uvicorn。

1. 编写 FastAPI 应用

请求时间戳已过期_请求中时间戳与服务器_请求服务器超时怎么办

首先,我们需要安装 FastAPI 和 uvicorn:

pip install fastapi

然后,我们创建一个简单的 FastAPI 应用:

from fastapi import FastAPI

# 创建 FastAPI 应用
app = FastAPI()

# 定义根路由
@app.get("/")
def read_root():
    return {"message""Hello, World!"}

小贴士:

2. 启动 uvicorn 服务器

保存上述代码为 main.py,然后通过 uvicorn 启动该应用:

uvicorn main:app --reload

访问 :8000,你就可以看到 "Hello, World!" 的返回值了。

3. 请求文档

FastAPI 提供了一个内置的交互式 API 文档页面。你可以访问 :8000/docs 来查看和测试 API。非常方便!这也是 FastAPI 被开发者青睐的原因之一。

如何在生产环境中优化 uvicorn

在开发环境中,使用 --reload 可以让代码改动后自动重启,但是在生产环境中,我们需要更多的优化。

1. 使用 启动 uvicorn

生产环境通常会使用 配合 uvicorn 来启动应用,这样可以充分利用多核 CPU 的性能。首先,我们需要安装 :

pip install gunicorn

然后,通过以下命令使用 启动 uvicorn:

请求服务器超时怎么办_请求时间戳已过期_请求中时间戳与服务器

gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app

这样可以让你的应用在生产环境中高效且稳定地运行。

2. 调整 uvicorn 的配置

uvicorn 提供了许多配置选项来优化性能。比如,我们可以增加 --workers 来启动多个工作进程,提高并发处理能力:

uvicorn main:app --workers 4

小贴士:

x ASGI 应用中的异步任务

uvicorn 最适合用于异步任务和并发处理的应用。如果你的应用需要处理大量的并发请求,使用异步编程将能极大地提高性能。

在 FastAPI 中,你可以使用 async 和 await 来创建异步路由:

from fastapi import FastAPI

app = FastAPI()

@app.get("/async")
async def async_hello():
    return {"message""Hello, async World!"}

通过异步路由,FastAPI 可以在请求过程中执行 I/O 操作而不会阻塞其他请求,这样可以处理更多的并发。

小练习

现在,橙子给大家布置一个小练习:

使用 uvicorn 启动一个 FastAPI 应用,支持一个异步接口 /async,该接口返回当前时间戳。

尝试修改 workers 和 reload 参数,观察性能差异。

今天的 Python 学习之旅就到这里啦!uvicorn 是一个非常高效的 ASGI 服务器,能够大幅提升 Python Web 应用的性能,特别适合高并发场景。记得动手敲代码,尝试搭建属于你自己的高效 Web 应用。祝大家学习愉快,Python 学习节节高!

WebRTC 媒体服务器

开源社区里可用的 WebRTC 媒体服务器有 Licode、OWT、Kurento、Jitsi、Janus、Medooze 和 。其中,能够作为 MCU 使用的有 Licode、OWT、Kurento、Medooze,能够作为 SFU 使用的有 Licode、OWT、Kurento、Jitsi、Janus、。

下面我们对其中几个具有代表性的媒体服务器进行介绍。

OWT

OWT(Open WebRTC Toolkit) 是 Intel 在 2014 年推出的针对 WebRTC 的开发套件。该套件包含了优化 Intel 硬件的服务器和客户端 SDK。Intel 持续为该套件增加新的特性,并于 2018 年将该套件开源。

OWT 既可以充当多点控制单元(MCU),又可以作为选择性转发单元(SFU) 使用。它还提供了对媒体进行解码、处理和重新编码后再将其发送回客户端的能力。

OWT 包含的主要功能如下。

OWT 应用层使用 Node.js 开发,媒体处理层使用了 C++ 语言,数据库使用 MongoDB,消息通信使用了 。

OWT 还提供了全平台的客户端 SDK,可以方便地整合到业务之中。

Kurento

Kurento 开源项目包含了一个 WebRTC 媒体服务器(KMS) 和一组与之通信的客户端 API。使用 Kurento 可以简化 Web 及移动端音视频应用程序的开发过程。Kurento 提供的功能包括音视频实时通信、实时转码、服务器端录制、合流、广播等。

Kurento 的特性有以下几个。

1.动态 WebRTC 媒体管道

Kurento 允许使用自定义媒体管道连接到 WebRTC 对等设备,例如 Web 浏览器和移动应用程序。这些媒体管道包括播放器、记录器、混音器等,即使在媒体已经连通的情况下,也可以在任何时间点对这些媒体管道进行组合、激活或停用。

2.客户端/服务器架构

使用 Kurento 开发的应用程序遵循客户端/服务器架构。Kurento 媒体服务器(KMS)提供了支持 Kurento 协议的 接口,该接口允许客户端应用程序定义管道拓扑。

3.Java和客户端应用程序

KMS 部署的典型示例包括 3 层体系结构,其中用户的浏览器通过中间客户端应用程序与 KMS 服务器交互。有几个官方的 Kurento 客户端库,支持在客户端应用程序中使用 Java 和 。遵循 协议,可以轻松开发自己的客户端 SDK。

sdn控制与转发分离_多点控制单元 选择转发单元_mpls控制平面和转发平面

4.第三方模块

Kurento 媒体服务器具有基于插件的可扩展结构,该结构允许第三方自定义模块。通过自定义模块,可以将任何媒体处理算法集成到 WebRTC 应用程序中,例如集成计算机视觉增强现实、视频索引和语音分析等。

Kurento Media Server 的代码是开源的,根据Apache License Version 2.0 的条款发布可在 GitHub 上免费获得。

Janus

采用C语言实现的 Janus 是一个 Liux 风格编写的 WebRTC 媒体服务器开源项目,支持在 Linux/MacOS下编译、部署,但不支持 Windows 环境。

Janus 分为两层: 插件层和传输层。Janus 插件的设计类似于 Nginx,用户可以根据自己的需要动态加载或卸载插件,也可以根据自身业务需要编写自己的插件。Janus 默认支持的插件如下。

媒体数据传输层主要实现了 WebRTC 中的流媒体及其相关协议,如 DTLS、ICE、SDP、RTP、SRTP、SCTP 等。

信令传输层用于处理Janus 的各种信令,支持的信令传输协议包括HTTP/HTTPS、/、NanoMsg、MQTT、PfUnix 和 。不过需要注意的是,有些协议是可以通过编译选项控制是否安装的,也就是说这些协议并不是默认全部安装的。另外,Janus的所有信令都采用JSON格式。

Janus 整体架构采用了插件的方案,这种架构方案非常优秀,用户可以根据自己的需要,非常方便地在上面编写应用程序。Janus 支持的功能非常多,比如 SIP、RTSP、音视频文件的播放和录制等,所以在融合性上比其他系统有非常大的优势。另外,Janus 的底层代码是由C语言编写的,性能非常强大。Janus 的开发、部署手册非常完善,因此它是一个非常优秀的开源项目。

是一个较新的 WebRTC 媒体服务器,其底层采用C++实现,外层使用Node.js 进行封装。 服务器端以 Node.js 模块的形式提供。

及其客户端库的设计目标如下。

支持 和 SVC,底层使用 C++ 开发,使用 libuv 作为异步IO事件处理库,保证了数据传输的高效性。 的实现逻辑非常清晰,它不关心上层应用如何做,只关心底层数据的传输,并将其做到极致。

与 Janus 相比, 更关注数据传输的实时性、高效性和简洁性,而 Janus 相对来讲更加复杂一些。

作为 SFU 媒体服务器的优点如下。

与其他的 SFU 相比, 最大的不同是它不能作为一个独立的服务器使用,而是以 Node.js 模块的形式存在,这样做的好处是可以整合到更大的应用程序中,不受自身的限制。在服务器端引人 的方式如下。

多点控制单元 选择转发单元_sdn控制与转发分离_mpls控制平面和转发平面

const mediasoup = require("mediasoup");  

在 Node.js 模块内部, 可以分为两个独立的组件: 一个 层,提供了适用于 Node.js 的现代 ; 一组处理媒体层(ICE、DTLS、RTP等)的C/C++子进程(Worker)。

这两个组件通过进程相互通信,但是,从开发人员的角度来看,应用程序只需要关注 API 层。

把每个实例称为一个子进程,通常在每核 CPU 上启动一个子进程。在子进程内部有多个 Router,每个 Router 相当于一个房间。在每个房间里可以有多个参与者,每个参与者在 中由一个 代理。换句话说,对于 Router,一个 就相当于一个用户。

分为3类 ,即 、 和 。

用于与 WebRTC 类型的客户端进行连接,如浏览器、WebRTC移动端等。

用于与传统的 RTP 类型的客户端连接,通过该 可以播放多媒体文件、执行媒体录制等。

用于实现 Router 之间的连接,也就是一个房间中的音视频流通过 传到另一个房间。由于一个 Router 只能运行在单核上,因此借助 可以充分利用多核 CPU 的特性,支持更多人同时在线。

每个 可以包含多个 和 。 表示媒体流的生产者,分为两种类型,即音频生产者和视频生产者。 表示媒体流的消费者,也分为两种类型,即音频消费者和视频消费者。

信令交互过程

的信令交互本质上与原生 WebRTC 的信令交互是一样的。 在其提供的客户端及服务器端库中封装了 WebRTC 的原生 API,如 ()、()等方法都封装在 的 API 中。

Mediasoup信令交互过程.png

通常由客户端发起信令交互,流程如下。

如果客户端创建的是发送通道,则进一步的流程如下。

如果客户端创建的是接收通道,则流程如下。

媒体服务器的选择

开源社区的几个媒体服务器各有特色,在实际应用中应根据项目需要进行选择。当需要采用MCU方案时,推荐使用OWT;当需要在服务器端对媒体流进行处理,比如增加人脸识别等功能时,推荐使用 Kurento; 当构建通用的WebRTC平台时,Janus 基于插件的模式更为合适; 如果希望打造单一的视频通话应用,则推荐使用 。