简体   繁体   English

如何触发 FastAPI/Uvicorn 的干净关闭

[英]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:长话短说:

  • APIs are meant to be long-running processes API 应该是长期运行的进程
  • there is a whole industry around virtualizing to manage the orchestration automatically of when to start or stop a service整个行业都围绕着虚拟化来自动管理何时启动或停止服务的编排
  • there is also "serverless" infrastructure you can hang any of your processes with you not having to spend any effort in this field as it is not meant to be a thing还有“无服务器”基础设施,你可以挂起你的任何流程,而不必在这个领域花费任何精力,因为它不是一个东西
  • If you still want to go against everyone else and do manage it your self you can do as this answered question如果你仍然想 go 对抗其他人并自己管理它,你可以按照这个回答的问题来做
    ##### 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.

相关问题 为什么我的 fastapi 或 uvicorn 会被关闭? - why is my fastapi or uvicorn getting shutdown? 测试 FastAPI 应用程序时如何触发生命周期启动和关闭? - How to trigger lifespan startup and shutdown while testing FastAPI app? 如何在 Google Colab 中运行 FastAPI / Uvicorn? - How to run FastAPI / Uvicorn in Google Colab? fastapi/uvicorn 如何并行化请求? - How does fastapi/uvicorn parallelize requests? Uvicorn/FastAPI 可执行文件 - Uvicorn/FastAPI executable 如何使用 FastAPI + uvicorn 在工作人员之间共享数据库连接? - How to share database connection between workers using FastAPI + uvicorn? 如何将 Uvicorn FastAPI 服务器作为来自另一个 Python 文件的模块运行? - How to run Uvicorn FastAPI server as a module from another Python file? Python - 如何在不阻塞线程的情况下使用 FastAPI 和 uvicorn.run? - Python - How to use FastAPI and uvicorn.run without blocking the thread? 在使用 pytest 进行测试时,如何使用 worker >= 2 干净地终止 Uvicorn + FastAPI 应用程序 - How to terminate a Uvicorn + FastAPI application cleanly with workers >= 2 when testing with pytest 使用 PyTest 进行测试时如何在后台启动 Uvicorn + FastAPI - How to start a Uvicorn + FastAPI in background when testing with PyTest
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM