本指南說明以 Python 程式設計語言編寫的 Cloud Run 服務最佳化方式,並提供背景資訊,協助您瞭解部分最佳化方式的取捨。本頁資訊可補充一般最佳化提示,也適用於 Python。
許多常見 Python 網路應用程式最佳做法和最佳化方式都圍繞著以下項目:
- 處理並行要求 (包括執行緒和非阻斷式 I/O)
- 使用連線集區和批次處理非必要的函式,例如將追蹤記錄和指標傳送至背景工作,藉此減少回應延遲時間。
最佳化容器映像檔
請使用下列方法調整容器映像檔,以縮短載入和啟動時間:
- 減少啟動時載入的檔案
- 最佳化 WSGI 伺服器
減少啟動時載入的檔案
如要縮短啟動時間,請只在啟動時載入必要檔案,並縮減檔案大小。如要處理大型檔案,請考慮採用下列選項:
將 AI 模型等大型檔案儲存在容器中,以便加快存取速度。建議在啟動或執行階段後載入這些檔案。
請考慮為開機時非必要的大型檔案 (例如媒體資產),設定 Cloud Storage 磁碟區掛載。
只從任何大量依附元件中匯入必要的子模組,或在程式碼中需要時匯入模組,而非在應用程式啟動時載入。
最佳化 WSGI 伺服器
Python 實作 WSGI 標準 (PEP-3333),讓應用程式與網路伺服器互動的方式標準化。gunicorn
是較常見的 WSGI 伺服器之一,許多範例文件都會使用這項工具。
最佳化 gunicorn
將下列 CMD
新增至 Dockerfile
,以改善 gunicorn
的叫用方式:
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app
如果您考慮變更這些設定,請根據各個應用程式調整工作站和執行緒的數量。舉例來說,請嘗試使用與可用核心數量相同的 worker 數量,並確認效能是否有改善,然後調整執行緒數量。如果設定的 worker 或執行緒過多,可能會造成負面影響,例如冷啟動延遲時間變長、耗用更多記憶體、每秒要求次數變少等。
根據預設,gunicorn
會在啟動時產生 worker,並監聽指定的通訊埠,甚至在評估應用程式程式碼之前就會這麼做。在這種情況下,您應為服務設定自訂啟動探測器,因為 Cloud Run 預設啟動探測器會在容器執行個體開始監聽 $PORT
時,立即將其標示為健康狀態。
如果您想變更這項行為,可以使用 --preload
設定叫用 gunicorn
,在監聽前評估應用程式程式碼。這麼做有助於:
- 在部署期間找出嚴重的執行階段錯誤
- 節省記憶體資源
在新增此元素前,請先考量應用程式會預先載入哪些內容。
其他 WSGI 伺服器
您不必使用 gunicorn
在容器中執行 Python。只要容器按照容器執行階段合約監聽 HTTP 通訊埠 $PORT
,您就可以使用任何 WSGI 或 ASGI 網頁伺服器。
常見的替代方案包括 uwsgi
、uvicorn
和 waitress
。
舉例來說,如果檔案名稱為 main.py
,且包含 app
物件,則下列叫用作業會啟動 WSGI 伺服器:
# uwsgi: pip install pyuwsgi
uwsgi --http :$PORT -s /tmp/app.sock --manage-script-name --mount /app=main:app
# uvicorn: pip install uvicorn
uvicorn --port $PORT --host 0.0.0.0 main:app
# waitress: pip install waitress
waitress-serve --port $PORT main:app
您可以將這些值新增為 Dockerfile
中的 CMD exec
行,也可以在使用 Google Cloud 的 Buildpack 時,將這些值新增為 Procfile
中的 web:
項目。
最佳化應用程式
您也可以在 Cloud Run 服務程式碼中進行最佳化,以縮短啟動時間和減少記憶體用量。
減少執行緒
您可以減少執行緒數量、使用非阻斷的回應策略,並避免背景活動,藉此最佳化記憶體。請勿寫入檔案系統,如一般提示頁面所述。
如果您想在 Cloud Run 服務中支援背景活動,請將 Cloud Run 服務設為以執行個體為基礎的帳單計費方式,這樣您就能在要求之外執行背景活動,同時仍可存取 CPU。
減少啟動工作
Python 網路應用程式在啟動期間可能需要完成許多工作,例如預先載入資料、暖機快取,以及建立連線集區。依序執行這些工作時,速度可能會變慢。不過,如果您想並行執行這些作業,請增加 CPU 核心數量。
Cloud Run 會傳送實際使用者要求,觸發冷啟動執行個體。將要求指派給新啟動的執行個體時,使用者可能會遇到長時間延遲的情況。
透過精簡版基本映像檔提升安全性
如要提升應用程式的安全性,請使用較少套件和程式庫的精簡版基本映像檔。
如果您選擇不從容器中的來源安裝 Python,請使用 Docker Hub 中的官方 Python 基本映像檔。這些映像檔是以 Debian 作業系統為基礎。
如果您使用的是 Docker Hub 中的 python
映像檔,建議您改用 slim
版本。這些映像檔較小,因為它們不包含用於建構輪子的多個套件,而您可能不需要為應用程式執行這項作業。python
映像檔隨附 GNU C 編譯器、前置處理器和核心公用程式。
如要找出基本映像檔中最大的十個套件,請執行下列指令:
DOCKER_IMAGE=python # or python:slim
docker run --rm ${DOCKER_IMAGE} dpkg-query -Wf '${Installed-Size}\t${Package}\t${Description}\n' | sort -n | tail -n10 | column -t -s $'\t'
由於這些低階套件較少,因此以 slim
為基礎的映像檔也提供較少的攻擊面,可降低潛在漏洞的風險。其中部分圖片可能不包含從原始碼建構輪組所需的元素。
您可以將 RUN apt install
行新增至 Dockerfile,藉此重新加入特定套件。詳情請參閱「在 Cloud Run 中使用系統套件」。
您也可以選擇非 Debian 容器。python:alpine
選項可能會產生更小的容器,但許多 Python 套件可能沒有預先編譯的輪子,無法支援以 Alpine 為基礎的系統。支援功能正在改善 (請參閱 PEP-656),但仍會有所不同。您也可以考慮使用 distroless base image
,因為這個檔案不含任何套件管理員、殼層或其他程式。
使用 PYTHONUNBUFFERED
環境變數記錄資料
如要查看 Python 應用程式未緩衝的記錄,請設定環境變數 PYTHONUNBUFFERED
。設定這個變數後,容器記錄會立即顯示 stdout
和 stderr
資料,而不會在累積一定數量的資料或關閉串流前,將資料保留在緩衝區中。
後續步驟
如需更多提示,請參閱