赞
踩
部署FastAPI应用程序相对容易。
部署应用程序意味着执行必要的步骤以使其可供用户使用。
对于Web API来说,通常涉及将上传到云服务器中,搭配一个性能和稳定性都不错的服务器程序,以便你的用户可以高效地访问你的应用程序,而不会出现中断或其他问题。
这与开发阶段形成鲜明对比,在开发阶段,你不断更改代码、破坏代码、修复代码,来回停止和重启服务器等。
根据你的使用场景和使用的工具,有多种方法可以实现此目的。
你可以使用一些工具自行部署服务器,你也可以使用能为你完成部分工作的云服务,或其他可能的选项。
FastAPI已在许多应用程序和系统的生产环境中使用。并且测试覆盖率保持在100%。但其开发进度仍在快速推进。
经常添加新功能,定期修复错误,并且代码仍在持续改进。
这就是为什么当前版本仍然是0.x.x
,这反映出每个版本都可能有Breaking changes。这遵循语义版本控制的约定。
你现在就可以使用FastAPI创建生产环境应用程序,你只需确保使用的版本可以与其余代码正确配合即可。
fastapi
版本你应该做的第一件事是将你正在使用的FastAPI版本”固定“到你知道适用于你的应用程序的特定最新版本。
例如,假设你在应用程序中使用版本0.45.0
。
如果你使用requirements.txt
文件,你可以使用以下命令指定版本:
fastapi==0.45.0
这意味着你将使用版本0.45.0
。
或者你也可以将其固定为:
fastapi>=0.45.0,<0.46.0
这意味着你将使用0.45.0
或更高版本,但低于0.46.0
,例如,版本0.45.2
仍会被接受。
人们很容易认为HTTPS仅仅是”启用“或”未启用“的东西。
但实际情况笔者复杂得多。
要从用户的视角了解HTTPS的基础知识,请查看https://howhttps.works/。
现在,从开发人员的视角,在了解HTTPS时需要记住以下几点:
通常的做法是在服务器上运行一个程序/HTTP服务器并管理所有HTTPS部分:接收加密的HTTPS请求,将解密的HTTP请求发送到在同一服务器中运行的实际HTTP应用程序(在本例中那个为FastAPI应用程序),从应用程序中获取HTTP响应,使用适当的HTTPS证书对其进行加密并使用HTTPS将其发送回客户端。此服务器通常被称为TLS终止代理。
你可以用作TLS终止代理的一些选项包括:
在Let’s Encrypt之前,这些HTTPS证书由受信任的第三方出售。
过去,获得这些证书的过程非常繁琐,需要大量的文书工作,而且证书非常昂贵。
但随后Let‘s Encrypt创建了。
它是Linux基金会的一个项目。它以自动方式免费提供HTTPS证书。这些证书可以使用所有符合标准的安全加密,并且有效期很短(大约3个月),因此安全性实际上更好,因为它们的生命周期缩短了。
域可以被安全地验证并自动生成证书。这还允许自动更新这些证书。
我们的想法是自动获取和更新这些证书,以便你可以永远免费拥有安全地HTTPS。
这里有一个HTTPS API看起来是什么样的示例,我们会分布说明,并且主要关注对开发人员重要的部分。
第一步我们要先获取一些域名(Domain Name)。然后可以在DNS服务器(可能是你的同一家云服务器提供的)中配置它。
你可能拥有一个云服务器(虚拟机)或类似的东西,并且它会有一个固定公共IP地址。
在DNS服务器中,你可以配置一条记录(”A记录“)以将你的域名指向你服务器的公共IP地址。
这个操作一般只需要在最开始执行一次。
现在让我们关注真正的HTTPS部分。
首先,浏览器将通过DNS 服务器查询域名的IP是什么,在本例中为someapp.example.com
。
DNS服务器会告诉浏览器使用某个特定的IP地址。这将是你在DNS服务器中为你的服务器配置的公共IP地址。
然后,浏览器将在端口443(HTTPS端口)上与该IP地址进行通信。
通信的第一部分只是建立客户端和服务器之间的连接并决定它们将使用的加密密钥等。
客户端和服务器之间建立TLS连接的过程称为TLS握手。
服务器中只有一个进程可以侦听特定IP地址的特定端口。可能有其他进程在同一IP地址的其他端口上侦听,但每个IP地址和端口组合只有一个进程。
TLS(HTTPS)默认使用端口443
。这就是我们需要的端口。
由于只有一个进程可以监听此端口,因此监听端口的进程将是TLS终止代理。
TLS终止代理可以访问一个或多个TLS证书(HTTPS证书)。
使用上面讨论的SNI扩展,TLS终止代理将检查应该用于此连接的可用TLS(HTTPS)证书,并使用与客户端期望的域名相匹配的证书,
在这种情况下,它将使用someapp.example.com
的证书。
客户端已经信任生成该 TLS 证书的实体(在本例中为 Let’s Encrypt,但我们稍后会看到),因此它可以验证该证书是否有效。
然后,通过使用证书,客户端和 TLS 终止代理 决定如何加密 TCP 通信 的其余部分。 这就完成了 TLS 握手 部分。
此后,客户端和服务器就拥有了加密的 TCP 连接,这就是 TLS 提供的功能。 然后他们可以使用该连接来启动实际的 HTTP 通信。
这就是 HTTPS,它只是 安全 TLS 连接 内的普通 HTTP,而不是纯粹的(未加密的)TCP 连接。
现在客户端和服务器(特别是浏览器和 TLS 终止代理)具有 加密的 TCP 连接,它们可以开始 HTTP 通信。
接下来,客户端发送一个 HTTPS 请求。 这其实只是一个通过 TLS 加密连接的 HTTP 请求。
TLS 终止代理将使用协商好的加密算法解密请求,并将(解密的)HTTP 请求传输到运行应用程序的进程(例如运行 FastAPI 应用的 Uvicorn 进程)。
应用程序将处理请求并向 TLS 终止代理发送(未加密)HTTP 响应。
然后,TLS 终止代理将使用之前协商的加密算法(以someapp.example.com的证书开头)对响应进行加密,并将其发送回浏览器。
接下来,浏览器将验证响应是否有效和是否使用了正确的加密密钥等。然后它会解密响应并处理它。
客户端(浏览器)将知道响应来自正确的服务器,因为它使用了他们之前使用 HTTPS 证书 协商出的加密算法。
在同一台(或多台)服务器中,可能存在多个应用程序,例如其他 API 程序或数据库。
只有一个进程可以处理特定的 IP 和端口(在我们的示例中为 TLS 终止代理),但其他应用程序/进程也可以在服务器上运行,只要它们不尝试使用相同的 公共 IP 和端口的组合。
这样,TLS 终止代理就可以为多个应用程序处理多个域名的 HTTPS 和证书,然后在每种情况下将请求传输到正确的应用程序。
在未来的某个时候,每个证书都会过期(大约在获得证书后 3 个月)。
然后,会有另一个程序(在某些情况下是另一个程序,在某些情况下可能是同一个 TLS 终止代理)与 Let’s Encrypt 通信并更新证书。
TLS 证书 与域名相关联,而不是与 IP 地址相关联。
因此,要更新证书,更新程序需要向权威机构(Let’s Encrypt)证明它确实“拥有”并控制该域名。
有多种方法可以做到这一点。 一些流行的方式是:
通过拥有一个单独的系统来使用 TLS 终止代理来处理 HTTPS, 而不是直接将 TLS 证书与应用程序服务器一起使用 (例如 Uvicorn),你可以在 更新证书的过程中同时保持提供服务。
在远程服务器计算机上运行FastAPI应用程序所需的主要东西是ASGI服务器程序,例如Uvicorn。
有3个主要可选方案:
关于名称,有一个小细节需要记住。
”服务器“一词通常用于指远程/云计算机(物理机或虚拟机)以及在该计算机上运行的程序(例如Uvicorn)。
请记住,当您一般读到”服务器“这个名词时,它可能指的是这两者之一。
当提到远程主机时,通常将其称为服务器,但也称为机器(machine)、VM(虚拟机)、节点。这些都是指某种类型的远程计算机,通常运行Linux,您可以在其中运行程序。
您可以使用以下命令安装ASGI兼容服务器:
$ pip install "uvicorn[standard]"
您可以按照之前教程中的相同方式运行应用程序,但不使用reload
选项,例如:
$ uvicorn main:app --host 0.0.0.0 --port 80
这些示例运行服务器程序(例如Uvicorn),启动单个进程,在所有IP(0.0.0.0
)上监听预定义端口(例如80
)。
这是基本思路。但您可能需要处理一些其他事情,例如:
在部署FastAPI应用程序或任何类型的Web API时,有几个概念值得了解,通过掌握这些概念您可以找到最合适的方法来部署您的应用程序。
见原文https://fastapi.tiangolo.com/zh/deployment/concepts/
程序这个词通常用来描述很多东西:
python
、python.exe
或uvicorn
。进程 这个词通常以更具体的方式使用,仅指在操作系统中运行的东西(如上面的最后一点):
如果您检查操作系统中的“任务管理器”或“系统监视器”(或类似工具),您将能够看到许多正在运行的进程。
例如,您可能会看到有多个进程运行同一个浏览器程序(Firefox、Chrome、Edge 等)。 他们通常每个tab运行一个进程,再加上一些其他额外的进程。
在大多数情况下,当您创建Web API时,您希望它始终运行、不间断,以便您的客户端始终可以访问它。 这是当然的,除非您有特定原因希望它仅在某些情况下运行,但大多数时候您希望它不断运行并且可用。
当您设置远程服务器(云服务器、虚拟机等)时,您可以做的最简单的事情就是手动运行 Uvicorn(或类似的),就像本地开发时一样。
它将会在开发过程中发挥作用并发挥作用。
但是,如果您与服务器的连接丢失,正在运行的进程可能会终止。
如果服务器重新启动(例如更新后或从云提供商迁移后),您可能不会注意到它。 因此,您甚至不知道必须手动重新启动该进程。 所以,你的 API 将一直处于挂掉的状态。
一般来说,您可能希望服务器程序(例如 Uvicorn)在服务器启动时自动启动,并且不需要任何人为干预,让进程始终与您的 API 一起运行(例如 Uvicorn 运行您的 FastAPI 应用程序)。
为了实现这一点,您通常会有一个单独的程序来确保您的应用程序在启动时运行。 在许多情况下,它还可以确保其他组件或应用程序也运行,例如数据库。
可以完成这项工作的工具的一些示例是:
与确保应用程序在启动时运行类似,您可能还想确保它在挂掉后重新启动。
使用 FastAPI 构建 Web API 时,如果我们的代码中存在错误,FastAPI 通常会将其包含到触发错误的单个请求中。
对于该请求,客户端将收到 500 内部服务器错误,但应用程序将继续处理下一个请求,而不是完全崩溃。
尽管如此,在某些情况下,我们编写的一些代码可能会导致整个应用程序崩溃,从而导致 Uvicorn 和 Python 崩溃。
尽管如此,您可能不希望应用程序因为某个地方出现错误而保持死机状态,您可能希望它继续运行,至少对于未破坏的路径操作。
但在那些严重错误导致正在运行的进程崩溃的情况下,您需要一个外部组件来负责重新启动进程,至少尝试几次…
在大多数情况下,用于启动时运行程序的同一工具也用于处理自动重新启动。
对于 FastAPI 应用程序,使用像 Uvicorn 这样的服务器程序,在一个进程中运行一次就可以同时为多个客户端提供服务。
但在许多情况下,您会希望同时运行多个工作进程。
如果您的客户端数量多于单个进程可以处理的数量(例如,如果虚拟机不是太大),并且服务器的 CPU 中有 多个核心,那么您可以让 多个进程 运行 同时处理同一个应用程序,并在它们之间分发所有请求。
当您运行同一 API 程序的多个进程时,它们通常称为 workers。
现在,当程序将内容加载到内存中时,例如,将机器学习模型加载到变量中,或者将大文件的内容加载到变量中,所有这些都会消耗服务器的一点内存 (RAM) 。
多个进程通常不共享任何内存。 这意味着每个正在运行的进程都有自己的东西、变量和内存。 如果您的代码消耗了大量内存,每个进程将消耗等量的内存。
例如,如果您的代码加载 1 GB 大小的机器学习模型,则当您使用 API 运行一个进程时,它将至少消耗 1 GB RAM。 如果您启动 4 个进程(4 个工作进程),每个进程将消耗 1 GB RAM。 因此,您的 API 总共将消耗 4 GB RAM。
如果您的远程服务器或虚拟机只有 3 GB RAM,尝试加载超过 4 GB RAM 将导致问题。
到目前为止,通过文档中的所有教程,您可能已经在单个进程上运行了像Uvicorn这样的服务器程序。
部署应用程序时,您可能希望进行一些进程复制,以利用多核并能够处理更多请求。
在这里时将Gunicorn与Uvicorn worker进程一起使用。
Gunicorn主要是一个使用WSGI标准的应用服务器。这意味着Gunicorn可以为Flask和Django等应用程序提供服务。Gunicorn本身与FastAPI不兼容,因为FastAPI使用最新的ASGI标准。
但Gunicorn支持充当进程管理器并允许用户告诉它要使用哪个特定的worker类。然后Gunicorn将使用该类启动一个或多个worker进程。
Uvicorn有一个Gunicorn兼容的worker类。
使用这种组合,Gunicorn将充当进程管理器,监听端口和IP。它会将通信传输到运行Uvicorn类的worker进程。
然后与Gunicorn兼容的Uvicorn worker类将负责将Gunicorn发送的数据转换为ASGI标准以供FastAPI使用。
$ pip install "uvicorn[standard]" gunicorn
这将安装带有standard
扩展包(以获得高性能)的Uvicorn和Gunicorn。
接下来你可以通过以下命令运行Gunicorn:
$ gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:80 [19499] [INFO] Starting gunicorn 20.1.0 [19499] [INFO] Listening at: http://0.0.0.0:80 (19499) [19499] [INFO] Using worker: uvicorn.workers.UvicornWorker [19511] [INFO] Booting worker with pid: 19511 [19513] [INFO] Booting worker with pid: 19513 [19514] [INFO] Booting worker with pid: 19514 [19515] [INFO] Booting worker with pid: 19515 [19511] [INFO] Started server process [19511] [19511] [INFO] Waiting for application startup. [19511] [INFO] Application startup complete. [19513] [INFO] Started server process [19513] [19513] [INFO] Waiting for application startup. [19513] [INFO] Application startup complete. [19514] [INFO] Started server process [19514] [19514] [INFO] Waiting for application startup. [19514] [INFO] Application startup complete. [19515] [INFO] Started server process [19515] [19515] [INFO] Waiting for application startup. [19515] [INFO] Application startup complete.
main:app
:这与Uvicorn使用的语法相同,main
表示名为"main
"的Python模块,因此是文件main.py
。app
是FastAPI应用程序的变量名称。你可以想象main:app
相当于一个Pythonimport
语句,例如:
from main import app
因此,main:app
中的冒号相当于from main import app
中的Python import
部分。
--workers
:要使用的worker进程数量,每个进程将运行一个Uvicorn worker进程,在本例中为4个worker进程。--worker-class
:在worker进程中使用的与Gunicorn兼容的工作类。这里我们传递了Gunicorn可以导入和使用的类:
import uvicorn.workers.UvicornWorker
--bind
:这告诉Gunicorn要监听的IP和端口,使用冒号(:
)分隔IP和端口。如果您直接运行Uvicorn,则可以使用--host 0.0.0.0
和--port 80
,而不是--bind 0.0.0.0:80
(Gunicorn选项)。
在输出中,您可以看到它显示了每个进程的PID(进程ID)。
你可以看到:
Listening at: http://0.0.0.0:80
。uvicorn.workers.UvicornWorder
处的worker类。Gunicorn还将负责管理死进程和重新启动新进程。因此,这在一定程度上有助于上面列表中重启的概念。
Uvicorn也有一个选项可以启动和运行多个worker进程。
然而,到目前为止,Uvicorn处理worker进程的能力比Gunicorn更有限。因此,如果您想拥有这个级别(Python级别)的进程管理器,那么最好尝试使用Gunicorn作为进程管理器。
$ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。