從 Python 2.7 遷移至最新的 Python 3 執行階段

本頁面說明如何從第一代 Python 執行階段遷移至第二代。如要升級第二代應用程式,改用最新支援的 Python 版本,請參閱「升級現有應用程式」。

Python 2.7 已於 2024 年 1 月 31 日終止支援。現有的 Python 2.7 應用程式仍會繼續執行並接收流量。不過,如果應用程式使用的執行階段已過支援期限,App Engine 可能會禁止重新部署。建議您按照本頁面的指南,遷移至最新支援的 Python 版本。

遷移至 Python 3 執行階段後,您就能使用最新的語言功能,並以慣用程式碼建構更具可攜性的應用程式。Python 3 執行階段會採用 Python Software Foundation 提供的最新版開放原始碼 Python 解譯器。使用 Python 3 執行階段建構的應用程式,可以在應用程式中使用 Python 豐富的套件與架構生態系統,包含使用 C 程式碼的套件與架構在內,方法是在 requirements.txt 檔案中宣告依附元件。

執行階段遷移程序總覽

建議您採取下列漸進式做法遷移執行階段,在整個過程中維持應用程式的運作和可測試性:

  1. 升級應用程式,使其與 Python 3 相容。

    我們提供多種解決方案,協助您完成升級。例如,使用 SixPython-FuturePython-Modernize

    如要進一步瞭解執行階段遷移程序的這個步驟,請參閱 Python Software Foundation 文件網站上的「將 Python 2 程式碼移植到 Python 3」。

  2. 針對應用程式使用的任何 App Engine 隨附服務,選擇下列其中一種實作策略:

    1. 將 Python 2 應用程式中的舊版套裝組合服務遷移至套裝組合以外的服務、第三方服務或其他建議取代功能。 Google Cloud

    2. 繼續在 Python 3 應用程式中使用舊版套裝服務。這種做法可讓您在遷移週期稍後改用未綁定的服務。

    遷移每項服務後,請務必測試應用程式。

  3. 準備 Python 3 執行階段的 App Engine 設定檔app.yaml 的設定受到幾項重大異動影響,包括但不限於:

    • 系統現在會假設應用程式具備執行緒安全特性。如果應用程式並非執行緒安全,請在 app.yaml 中將 max_concurrent_requests 設為 1。這項設定可能會導致系統建立的執行個體數量,超出執行緒安全應用程式的需求,進而產生不必要的費用。
    • app.yaml 檔案不再將要求轉送至指令碼。您必須改用具有應用程式內路徑的網頁架構,並更新或移除 app.yaml 中的所有 script 處理常式。如需使用 Flask 架構執行這項操作的範例,請參閱 GitHub 中的 App Engine 遷移指南程式碼範例

      如要進一步瞭解如何變更這項設定和其他設定檔,請參閱「設定檔」一節。

  4. 在第二代執行階段中,應用程式記錄檔不再巢狀內嵌於要求記錄檔中。如要在記錄檔探索工具中顯示要求和應用程式記錄的巢狀檢視畫面,還需要執行其他步驟。詳情請參閱「遷移至 Cloud Logging」。

  5. 在 Python 3 環境中測試及部署升級後的應用程式。

    所有測試通過後,請將升級後的應用程式部署至 App Engine,但防止流量自動轉送至新版本。使用流量分配,將流量從 Python 2 執行階段的應用程式,緩慢遷移至 Python 3 執行階段的應用程式。如果遇到問題,您可以將所有流量轉送至穩定版,直到問題修正為止。

如需將 Python 2 應用程式轉換為 Python 3 的範例,請參閱這些額外資源

Python 2 和 Python 3 執行階段的主要差異

在執行階段遷移期間,您需要進行的大部分變更,都是因為 Python 2 和 Python 3 執行階段有下列差異:

記憶體用量差異

與第一代執行階段相比,第二代執行階段的記憶體用量基準較高。這是因為多項因素,例如基本圖片版本不同,以及兩代裝置計算記憶體用量的方式不同。

第二代執行階段會計算執行個體記憶體用量,方法是將應用程式程序使用的記憶體量,以及動態快取在記憶體中的應用程式檔案數量加總。為避免記憶體用量高的應用程式因超出記憶體限制而導致執行個體關閉,請升級至記憶體較多的較大執行個體類別

CPU 使用率差異

第二代執行階段在執行個體冷啟動時,CPU 使用率的基準可能會較高。視應用程式的縮放設定而定,這可能會產生非預期的副作用,例如:如果應用程式設定為根據 CPU 使用率進行縮放,則執行個體數量可能會超出預期。為避免發生這個問題,請檢查並測試應用程式的擴充設定,確保執行個體數量可接受。

要求標頭差異

第一代執行階段允許將含有底線的要求標頭 (例如 X-Test-Foo_bar) 轉送至應用程式。第二代執行階段會在主機架構中導入 Nginx。這項異動會導致第二代執行階段自動移除含有底線 (_) 的標頭。為避免應用程式發生問題,請勿在應用程式要求標頭中使用底線。

Gunicorn 工作人員差異

如果是 Python 3 以上的執行階段,Gunicorn 工作站數量會直接影響記憶體用量。記憶體用量增加的幅度與工作站數量增加的幅度成正比。如要減少記憶體耗用量,請考慮減少 Gunicorn 工作站數量。如需設定 Gunicorn 工作人員數量的操作說明,請參閱進入點最佳做法

Python 2 和 Python 3 之間的相容性問題

Python 3 於 2008 年首次發布時,該語言導入一些與前版不相容的變更。其中有些變更只需要稍微更新程式碼,例如將 print 陳述式變更為 print() 函式。其他變更可能需要大幅更新程式碼,例如更新處理二進位資料、文字和字串的方式。

包含 Python 標準程式庫在內的許多常用開放原始碼程式庫,在 Python 2 移至 Python 3 時也有所變更。

Python 3 執行階段中的 App Engine 套裝組合服務

為減少遷移作業的負擔和複雜度,App Engine 標準環境可讓您在 Python 3 執行階段存取許多舊版組合式服務和 API,例如 Memcache。Python 3 應用程式可透過語言慣用程式庫呼叫套裝組合服務 API,並存取與 Python 2 執行階段相同的功能。

您也可以選擇使用 Google Cloud 產品,這些產品提供的功能與舊版套裝組合服務類似。建議您遷移至未綁定的 Google Cloud 產品,以便享有持續改善的服務和新功能。

如果套裝組合服務在Google Cloud中無法做為獨立產品使用,例如圖片處理、搜尋和訊息服務,您可以使用建議的第三方供應商或其他解決方法

設定檔

如要在 App Engine 標準環境的 Python 3 執行階段中執行應用程式,您可能需要變更 App Engine 使用的部分設定檔:

  • app.yamlapp.yaml 設定檔中部分欄位的行為已受到修改。移除所有已淘汰的欄位,並按照遷移指南所述更新其他欄位。

  • requirements.txt. 建立這個檔案,安裝第三方依附元件,包括需要原生 C 擴充功能的 Python 套件。在 Python 3 執行階段中部署應用程式時,App Engine 會自動安裝這些依附元件。先前如要在 Python 2 執行階段中安裝依附元件,您必須在這個檔案中列出複製或自行組合的程式庫,然後執行 pip install -t lib -r requirements.txt 指令。

  • appengine_config.py。Python 3 執行階段不會使用這個檔案,部署時也會忽略。先前在 Python 2 執行階段中,這個檔案用於設定 Python 模組,並將應用程式指向複製或自行組合的第三方程式庫。

需要網頁架構才能將動態內容要求轉送至適當位置

在 Python 2 執行階段中,您可以在 app.yaml 檔案中建立網址處理常式,指定在要求特定網址或網址模式時要執行的應用程式。

在 Python 3 執行階段中,應用程式必須使用 Flask 或 Django 等網路架構,轉送動態內容的要求,而不是使用 app.yaml 中的 URL 處理常式。如要處理靜態內容,您可以在應用程式的 app.yaml 檔案中繼續建立網址處理常式

只包含靜態內容的應用程式

在 App Engine 上託管靜態網路應用程式時,您可以在 app.yaml 檔案中指定處理常式,將網址對應至靜態檔案。

在 Python 2 中,如果要求與 app.yaml 檔案中指定的任何處理常式都不相符,App Engine 會傳回 404 錯誤碼。

在 Python 3 中,如果要求與任何處理常式都不相符,App Engine 會尋找 main.py 檔案,如果找不到,就會傳回 5xx 錯誤。main.py由於只有靜態內容的 App Engine 應用程式不需要 main.py 檔案,因此大多數使用者都會看到這個錯誤,此外也會在應用程式記錄中看到執行個體啟動錯誤。

如要維持在沒有任何靜態處理常式相符時傳回 404 錯誤的行為,並避免記錄檔發生錯誤,您可以採取下列任一做法:

  • app.yaml 檔案中新增指向空白目錄的全部接收靜態處理常式
  • main.py 檔案中新增簡單的動態應用程式,傳回 404 錯誤

使用任一選項的範例如下:

app.yaml

在根應用程式目錄中建立空白目錄,例如 empty/。 在 app.yaml 檔案的處理常式部分,於結尾建立新的處理常式,以便擷取所有其他網址模式,並在 static_filesupload 元素中指定 empty 目錄:

  handlers:
  - url:
    .
    .
    .
  - url: /(.*)$
    static_files: empty/\1
    upload: empty/.*$

main.py

建立 main.py 檔案,並加入下列程式碼來傳回 404 錯誤:

  def app(env, start_response):
    start_response('404 Not Found', [('Content-Type','text/html')])
    return [b"Not Found"]

測試

建議您使用 Python 慣用的測試方法,而非依附於 dev_appserver 的測試方法。舉例來說,您可以透過 venv 建立獨立的本機 Python 3 環境,並且使用任何標準 Python 測試架構來編寫自己的單元、整合功能和系統測試。您也可以考慮設定開發版本的服務,或是使用適用於許多 Google Cloud 產品的本機模擬器。

您也可以使用支援 Python 3 的 dev_appserver 預覽版。如要進一步瞭解這項測試功能,請參閱「使用本機開發伺服器」。

部署中

Python 3 不支援透過 appcfg.py 進行部署。請改用 gcloud 指令列部署應用程式。

記錄

Python 3 執行階段的記錄作業遵循 Cloud Logging 的記錄標準。在 Python 3 執行階段中,應用程式記錄不再與要求記錄捆綁在一起,而是分開記錄。如要進一步瞭解如何在 Python 3 執行階段中讀取及寫入記錄,請參閱記錄指南

其他遷移資源

如要進一步瞭解如何將 App Engine 應用程式遷移至獨立的 Cloud 服務或 Python 3 執行階段,請參閱下列 App Engine 資源: