[英]How to trigger clean shutdown of FastAPI/Uvicorn
I am running a number of FastAPI instances with uvicorn with python's subprocess.Popen.我正在使用 uvicorn 和 python 的 subprocess.Popen 运行许多 FastAPI 实例。 I have a small GUI made with PySimpleGUI with which I want to be able to close servers and restart them at will.我有一个用 PySimpleGUI 制作的小型 GUI,我希望能够使用它关闭服务器并随意重新启动它们。
The first problem I encountered is that, at least in Windows, starting the uvicorn server appear to create not one, but two, new processes, and calling Popen.terminate()
only closes one of these processes, which does not free up the port associated with the server.我遇到的第一个问题是,至少在 Windows 中,启动 uvicorn 服务器似乎创建的不是一个,而是两个新进程,调用Popen.terminate()
只会关闭其中一个进程,不会释放端口与服务器关联。 I fixed this problem using the psutil package to check what new processes have been created after I instantiate a Popen object, and track and terminate the second process with psutil.我使用 psutil package 修复了这个问题,以检查在我实例化 Popen object 之后创建了哪些新进程,并使用 psutil 跟踪和终止第二个进程。
What is still a major problem, is that calling psutil.terminate()
on the process does not call the FastAPI function under @app.on_event("shutdown")
.仍然存在的主要问题是,在进程上调用psutil.terminate()
不会调用@app.on_event("shutdown")
下的 FastAPI function。 In the past, we have run all of our servers in individual terminal windows, and find that ctrl-c on those terminal windows will call the shutdown event, but I have found no other way of doing so.过去,我们在单个终端 windows 中运行我们所有的服务器,发现在这些终端 windows 上的 ctrl-c 会调用关闭事件,但我没有找到其他方法。 ctrl-c on my interface will obviously take down the interface and all the servers, and is somewhat unreliable in hitting the shutdown events for all the servers.我界面上的 ctrl-c 显然会关闭界面和所有服务器,并且在触发所有服务器的关闭事件时有些不可靠。 My other idea was use psutil.send_signal(signal.CTRL_C_EVENT)
, but this has the same effect as calling ctrl-c in terminal.我的另一个想法是使用psutil.send_signal(signal.CTRL_C_EVENT)
,但这与在终端中调用 ctrl-c 具有相同的效果。
So I am at a loss.所以我很茫然。 I have seen multiple posts around saying that this is a general shortcoming of uvicorn, but have not seen anything that directly confirms my own experience or offers a solution.我看到很多帖子都说这是uvicorn的普遍缺点,但没有看到任何直接证实我自己经验或提供解决方案的东西。 I also know that the "shutdown" and "startup" events in FastAPI are ported in from Starlette, and are not very well documented in either package. I have seen suggestions to use guvicorn, but my brief look into that confirmed that it is not compatible with windows. Any suggestions?我也知道 FastAPI 中的“关闭”和“启动”事件是从 Starlette 移植过来的,并且在 package 中都没有很好的记录。我看到了使用 guvicorn 的建议,但我的简短调查证实它不是与 windows 兼容。有什么建议吗?
TL;DR:长话短说:
##### SOLUTION #####
pid = proc.pid
parent = psutil.Process(pid)
for child in parent.children(recursive=True):
child.kill()
##### SOLUTION END ####
A bit of explanation:一点解释:
From the conception of Rest API as an architecture pattern it was meant to be awaiting always for user's requests coming over the web. it has never been the general intent to manage gracefully and develop a product to handle gracefully the shut down of something that "was meant to run forever" and we build processes to do work to keep it running 24/7/365 as an industry.从 Rest API 作为一种架构模式的概念来看,它意味着始终等待用户通过 web 发出的请求。优雅地管理和开发产品以优雅地关闭“曾经是”的东西从来都不是一般的意图意味着永远运行”,我们构建流程以使其作为一个行业保持 24/7/365 运行。
If you ever want to leverage the ability to start or stop one to many APIS simultaneously withing the same device is highly recommended d you at least go with something like containers and Kube.netes and just scripting commands against the CLI of Kube.netes for such purpose.如果你想利用同一设备同时启动或停止一对多 APIS 的能力,强烈建议你至少 go 使用容器和 Kube.netes 之类的东西,并且只需针对 Kube.netes 的 CLI 编写脚本命令即可目的。 In exchange for the extra effort you will gain process isolation from others and the base OS layer ( which will still be less effort than building all that tooling yourself on your own. My personal favorite is not doing even that and going straight with lambdas as is way easier and better in so many ways. Don't take it from me but from one of the industry-leading companies, Cloudflare and their statements on the subject作为额外努力的交换,您将获得与其他人和基础操作系统层的进程隔离(这仍然比自己构建所有工具要少。我个人最喜欢的是甚至不这样做并直接使用 lambdas在很多方面都更容易、 更好
Serverless computing offers a number of advantages over traditional cloud-based or server-centric infrastructure.与传统的基于云或以服务器为中心的基础架构相比,无服务器计算具有许多优势。 For many developers, serverless architectures offer greater scalability, more flexibility, and quicker time to release, all at a reduced cost.对于许多开发人员而言,无服务器架构提供了更大的可扩展性、更大的灵活性和更快的发布时间,而且成本更低。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.