[英]Unclosed socket due to spawn child processes using multiprocessing
我真的不明白 http 請求是怎么回事。 當我啟動子進程並且 uvicorn timeout_keep_alive
超時時,我嘗試在瀏覽器中點擊“停止”並獲得無限加載並且沒有 HTTP 連接日志。 但是,如果我嘗試單擊其他按鈕或刷新頁面,它會起作用並且我會收到兩個響應。
netstat 顯示 socket bind 端口60862
已打開,但 uvicorn 日志:
TRACE: 127.0.0.1:60862 - HTTP connection lost
。
import multiprocessing
import os
import time
import uvicorn
from fastapi import FastAPI
app = FastAPI()
processes = []
def keep_alive_process():
while True:
print(f"process {os.getpid()} is alive")
time.sleep(1)
@app.post("/start")
async def start_processes():
for i in range(4):
process = multiprocessing.Process(target=keep_alive_process,
args=())
processes.append(process)
process.start()
return {'status': 'started'}
@app.post("/stop")
async def stop_processes():
for process in processes:
process.kill()
processes.clear()
return {'status': 'stopped'}
if __name__ == '__main__':
uvicorn.run('main:app', timeout_keep_alive=10, log_level='trace')
TRACE: 127.0.0.1:60862 - HTTP connection made
TRACE: 127.0.0.1:60862 - ASGI [2] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8010), 'client': ('127.0.0.1', 60862), 'scheme': 'http', 'root_path': '', 'headers': '<...>', 'method': 'POST', 'path': '/start', 'raw_path': b'/start', 'query_string': b''}
TRACE: 127.0.0.1:60862 - ASGI [2] Send {'type': 'http.response.start', 'status': 200, 'headers': '<...>'}
TRACE: 127.0.0.1:60862 - ASGI [2] Send {'type': 'http.response.body', 'body': '<20 bytes>'}
TRACE: 127.0.0.1:60862 - ASGI [2] Completed
process 63912 is alive
process 63913 is alive
process 63914 is alive
process 63915 is alive
INFO: 127.0.0.1:60862 - "POST /start HTTP/1.1" 200 OK
process 63912 is alive
process 63913 is alive
TRACE: 127.0.0.1:60862 - HTTP connection lost
....
process 63912 is alive
INFO: 127.0.0.1:59092 - "POST /stop HTTP/1.1" 200 OK
INFO: 127.0.0.1:59092 - "POST /stop HTTP/1.1" 200 OK
TRACE: 127.0.0.1:59092 - HTTP connection made
TRACE: 127.0.0.1:59092 - ASGI [3] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8010), 'client': ('127.0.0.1', 59092), 'scheme': 'http', 'root_path': '', 'headers': '<...>', 'method': 'POST', 'path': '/stop', 'raw_path': b'/stop', 'query_string': b''}
TRACE: 127.0.0.1:59092 - ASGI [3] Send {'type': 'http.response.start', 'status': 200, 'headers': '<...>'}
TRACE: 127.0.0.1:59092 - ASGI [3] Send {'type': 'http.response.body', 'body': '<20 bytes>'}
TRACE: 127.0.0.1:59092 - ASGI [3] Completed
TRACE: 127.0.0.1:59092 - ASGI [4] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8010), 'client': ('127.0.0.1', 59092), 'scheme': 'http', 'root_path': '', 'headers': '<...>', 'method': 'POST', 'path': '/stop', 'raw_path': b'/stop', 'query_string': b''}
TRACE: 127.0.0.1:59092 - ASGI [4] Send {'type': 'http.response.start', 'status': 200, 'headers': '<...>'}
TRACE: 127.0.0.1:59092 - ASGI [4] Send {'type': 'http.response.body', 'body': '<20 bytes>'}
TRACE: 127.0.0.1:59092 - ASGI [4] Completed
TRACE: 127.0.0.1:59092 - HTTP connection lost
所以我唯一的決定(解決方法)是將 timeout_keep_alive uvicorn 參數設置為零並使用 Fastapi 的 BackgroundTask。 套接字在發送響應后立即關閉,但進程在發送響應后產生。
''' multiprocessing 模塊使用進程分叉技術,其中文件和套接字描述符照常由子進程繼承。 因此,子進程將使用與父進程相同的連接套接字'''
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.