我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」有說明如何使用uvicorn來啟動FastAPI服務, 假設今天我們的API是一個CPU密集型的運算服務時, 通常我們會希望開啟多個行程來幫忙處理, 那麼大致上的撰寫方式會像這樣:
app = FastAPI(
title='api文件 🚀',
description=description,
lifespan=lifespan,
openapi_tags=tags_metadata,
)
...
uvicorn.run(
app,
host='0.0.0.0',
port=args.port,
workers=args.workers,
)
But…啟動時卻發生了「WARNING: You must pass the application as an import string to enable 'reload' or 'workers'.」這樣的訊息造成無法順利啟動。
原因是 uvicorn.run()
內部直接啟動了應用程式,但要啟用多個 worker(或使用 --reload
),必須將應用程式作為匯入字串傳遞給 uvicorn
命令行工具或其他工具(如 gunicorn
),這樣才能讓 uvicorn
自行管理多進程模式。
# main:app 是 main.py 中定義的應用程式 app 物件。
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
或者透過python的subprocess呼叫啟動…
args = parser.parse_args()
subprocess.run([
"uvicorn",
"main:app",
"--host", "0.0.0.0",
"--port", str(args.port),
"--workers", str(args.workers)
])
args = parser.parse_args()
uvicorn.run(
"main:app",
host="0.0.0.0",
port=args.port,
workers=args.workers,
)
uvicorn
的多 worker 模式是基於多進程啟動的,而多進程需要每個子進程能夠獨立地匯入應用程式對象, 傳遞匯入字串(如 main:app
)告訴 uvicorn
如何定位和載入應用程式。
雖然這種方式可以讓API在沒有代理服務器Nginx的情況之下完成分流的動作, 但仍有一些限制在, 比如說共享變數的傳遞(【💊 Python的解憂錦囊 - FastAPI】Sharing State讓路由共享資訊)就會發生無法正常傳遞的狀況, 不過沒關係, 我們會在「【💊 Python的解憂錦囊 - FastAPI】多個worker如何共享數據?」教您如何解決這樣的問題。