在Google Cloud Run上运行FastAPI(Docker镜像)

4
我想构建一个Docker镜像,在Google Cloud Run上运行FastAPI。FastAPI使用Uvicorn作为ASGI服务器,Uvicorn建议与Uvicorn工作类一起使用Gunicorn进行生产部署。FastAPI本身还有一些关于如何使用Gunicorn和Uvicorn的优秀文档。我甚至发现FastAPI提供了一个官方镜像,将两者组合起来(uvicorn-gunicorn-fastapi-docker),但是这个镜像带有警告

你可能正在使用Kubernetes或类似的工具。如果是这种情况,你可能不需要这个镜像(或任何其他类似的基础镜像)。最好从头开始构建一个Docker镜像。

这个警告基本上解释了复制将在“集群级别”处理,不需要在“进程级别”处理。这是有道理的。但我不太确定Cloud Run是否属于此类?实质上,它是一个抽象和托管的Knative服务,因此在Kubernetes上运行。
我的问题是,我应该在Dockerfile中安装Gunicorn和Uvicorn,并在进程级别处理复制吗?类似于:
CMD ["gunicorn", "app.main:app", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:80"]

我应该坚持使用单一进程的Uvicorn,让Cloud Run(Kubernetes)在集群级别上处理复制吗?例如:
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
1个回答

4

A. 首先让我们考虑大规模问题。

目前,Cloud Run实例最多可以设置为1000 并发请求,可以设置4 vCPUs的CPU。

回到基础知识。Cloud Run将扩展许多实例,每个实例将单独工作,并且每个实例可以处理最大允许的并发请求,因此每个实例可以处理1000个请求。如果您设置多个CPU,则需要处理多个进程。

当我们谈论如此大的数字时,我们需要谨慎。如果您的容器在CPU /内存方面足够大以处理此流量,则可能希望使用进程管理器(gunicorn)启动多个Uvicorn线程(worker),就像您引用的图像一样。所以您可以使用docker容器。

B. 处于小规模的情况。

另一方面,如果您设置1个vCPU并且是单线程的,则不需要使用gunicorn作为进程管理器。您仍然可以启用并发性,但不在顶层,而是在较低级别上,适合于您的1个vCPU模型,例如80个并发请求。在这种情况下,当有大量流量时,Cloud Run将启动许多实例,并依赖于Cloud Run根据需要生成尽可能多的实例,这非常好。就像在您的简单容器之上的Kubernetes一样。
我建议从单个进程开始,构建一个不使用引用容器的容器,并仅在知道使用更大的实例会带来收益(成本方面)时将B替换为版本A。

感谢提供规模细分建议。只是为了明确,您建议在小规模上从我的第二个代码片段开始:在Dockerfile中使用单个进程的Uvicorn(没有Uvicorn工作进程和Gunicorn)? - ianyoung
2
是的,当然,试一下吧。 - Pentium10

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接