如何在 Flask 應用程式中使用 App Engine Memcache (單元 12)

1. 總覽

無伺服器遷移站系列的程式碼研究室系列 (自助式實作教學課程) 和相關影片,旨在引導 Google Cloud 無伺服器開發人員透過一或多種遷移作業 (主要用於遷移舊版服務) 逐步翻新應用程式。這麼一來,您的應用程式就能更具可攜性,並提供更多選擇和使用彈性,進而整合及使用更多 Cloud 產品,也更容易升級至較新的語言版本。本系列課程一開始將著重在最早的 Cloud 使用者 (主要是 App Engine (標準環境) 開發人員),但涵蓋其他無伺服器平台,包括 Cloud FunctionsCloud Run 或其他無伺服器平台 (如適用)。

本程式碼研究室會說明如何在模組 1 程式碼研究室中,納入及使用 App Engine Memcache範例應用程式。我們會透過單元 12 教學課程增加 Memcache 的用法,然後在下一個單元 13 中遷移至 Cloud Memorystore

在接下來的研究室中

  • 使用 App Engine Memcache API/程式庫
  • 將快取新增至基本的 Python 2 Flask App Engine NDB 應用程式

軟硬體需求

問卷調查

您會如何使用這個教學課程?

僅供閱讀 閱讀並完成練習

您對 Python 的使用體驗有何評價?

新手 中級 還算容易

針對使用 Google Cloud 服務的經驗,您會給予什麼評價?

新手 中級 還算容易

2. 背景

如要從 App Engine Memcache 遷移,請將相關用途新增至單元 1 程式碼研究室產生的現有 Flask 和 App Engine NDB 應用程式。範例應用程式會顯示使用者最近十次造訪的情形。如果同一位使用者重新整理瀏覽器,最好不要持續建立新的 Visit 實體並擷取 Datastore 中的最近造訪資料,因此我們會快取最近的造訪。

如果同一個訪客到達網頁,快取就會傳回這些造訪。如果網站有新的使用者造訪,或是已經過了 1 小時,系統就會清除快取,並以最新的項目替代 (更不用說是註冊新的造訪)。實作這項 App Engine Memcache 整合功能之後,我們可以在下一個 (單元 13) 程式碼研究室中將其遷移至 Cloud Memorystore

本教學課程包含下列步驟:

  1. 設定/事前作業
  2. 更新設定
  3. 修改應用程式程式碼

3. 設定/事前作業

在開始教學課程的主要部分之前,我們先設定專案、取得程式碼,然後部署基準應用程式,以便瞭解要開始使用有效的程式碼。

1. 設定專案

如果您已完成單元 1 程式碼研究室,建議您重複使用相同的專案和程式碼。或者,您可以建立新的專案,或是重複使用其他現有專案。請確認專案具備有效的帳單帳戶,且 App Engine 已啟用。

2. 取得基準範例應用程式

本程式碼研究室的必要條件之一,是擁有正常運作的模組 1 範例應用程式。如果您沒有課程,請先完成任一教學課程 (上方的連結),再繼續操作。如果您熟悉其中的內容,可以直接從下方的單元 1 程式碼開始操作。

無論您使用自有還是我們的模組,我們都會開始使用單元 1 程式碼。本程式碼研究室會逐步引導您完成每個步驟,最後程式碼會與單元 11 存放區資料夾 (FINISH) 中顯示的程式碼類似。

模組 1 STARTing 檔案 (您的或我們的) 目錄應如下所示:

$ ls
README.md               main.py                 templates
app.yaml                requirements.txt

3. (重新) 部署基準應用程式

您目前需執行的準備作業步驟:

  1. 請重新熟悉 gcloud 指令列工具。
  2. 使用 gcloud app deploy 重新部署範例應用程式
  3. 確認應用程式在 App Engine 上執行,沒有問題

成功執行上述步驟之後,如果系統顯示網頁應用程式的運作情況 (類似以下的輸出內容),您就可以開始在應用程式中使用快取功能。

a7a9d2b80d706a2b.png

4. 更新設定

不需要對標準 App Engine 設定檔 (app.yamlrequirements.txtappengine_config.py) 進行任何變更。

5. 修改應用程式檔案

由於我們只會新增 App Engine API,因此不需要使用任何外部套件,因此不需要更新設定檔 (app.yamlrequirements.txtappengine_config.py)。由於只有一個應用程式檔案 (main.py),因此這個部分的所有變更只會影響該檔案。

匯入

最重要的步驟是匯入 Memcache 程式庫 google.appengine.api.memcache。由於我們要快取 1 小時內的最新造訪記錄,因此我們還要加入一小時的秒數常數。以下是您的程式碼變更之前的模樣,以及這項變更:

變更前:

from flask import Flask, render_template, request
from google.appengine.ext import ndb

app = Flask(__name__)

變更後:

from flask import Flask, render_template, request
from google.appengine.api import memcache
from google.appengine.ext import ndb

app = Flask(__name__)
HOUR = 3600

透過 Memcache 支援新增快取

最重大的變化,是在應用程式中加入快取功能。更具體來說,我們應該快取最近的造訪記錄、查看是否有快取的造訪資料,並嘗試運用快取結果,盡可能地運用快取結果。應用程式要採取哪些步驟來達成目標:

  1. 設定目前的造訪記錄,並命名為 visitor
  2. 嘗試從快取擷取最新的 visits
  3. 如果快取沒有任何內容,或最新訪客 (visits[0]['visitor']) 與目前的 visitor 不同,請儲存這次最新的造訪記錄、擷取最近的造訪記錄,並快取這些造訪一小時。
  4. 透過網頁範本向使用者顯示 visits

以下是異動前後的版本:

變更前:

@app.route('/')
def root():
    'main application (GET) handler'
    store_visit(request.remote_addr, request.user_agent)
    visits = fetch_visits(10)
    return render_template('index.html', visits=visits)

變更後:

@app.route('/')
def root():
    'main application (GET) handler'
    # check for (hour-)cached visits
    ip_addr, usr_agt = request.remote_addr, request.user_agent
    visitor = '{}: {}'.format(ip_addr, usr_agt)
    visits = memcache.get('visits')

    # register visit & run DB query if cache empty or new visitor
    if not visits or visits[0]['visitor'] != visitor:
        store_visit(ip_addr, usr_agt)
        visits = list(fetch_visits(10))
        memcache.set('visits', visits, HOUR)  # set() not add()

    return render_template('index.html', visits=visits)

以下是所做變更的基本示意圖:

b1242503602f7bf0.png

以上是將 App Engine memcache 新增至模組 1 範例應用程式的所有必要變更。接著,請建構並部署這個應用程式,看看能否正常運作!

6. 摘要/清除

本節總結此程式碼研究室的內容,做法是部署應用程式,確認應用程式是否正常運作,以及任何反映的輸出內容。驗證應用程式後,請執行所有清除步驟,並考慮後續步驟。

部署及驗證應用程式

使用 gcloud app deploy 重新部署應用程式,並確認應用程式可以正常運作。您的程式碼現在應與 FINISH (模組 12 資料夾) 中的內容相符。輸出內容應該會與您先前部署的模組 1 應用程式相同:

a7a9d2b80d706a2b.png

我們不僅提升了同一使用者的使用者體驗,重新整理後,您應該直接從快取取得結果,這既不會建立新的造訪,也不會進行 Datastore 擷取。

恭喜您完成單元 12 程式碼研究室,瞭解如何將 App Engine memcache 服務加入範例應用程式。現在您可以選擇將這個 Python 2 應用程式移植到 Python 3。

清除所用資源

一般

如果您現階段已完成設定,建議您停用 App Engine 應用程式,以免產生帳單費用。不過,如果您想測試或進行其他測試,App Engine 平台提供免費配額,而且只要不超出用量限制,就不需支付任何費用。這適用於運算,但相關 App Engine 服務可能也會產生費用,詳情請參閱定價頁面。如果這項遷移作業涉及其他 Cloud 服務,我們會另外計費。無論採用哪種情況,請參閱「本程式碼研究室的專屬」以下章節。

如要完整揭露,部署至 Google Cloud 無伺服器運算平台 (如 App Engine) 會產生少許建構和儲存空間費用Cloud Build 提供的免費配額與 Cloud Storage 相同。該映像檔的儲存空間會佔用部分配額。不過,您可能居住的區域沒有這類免費方案,因此請留意儲存空間用量,盡可能降低潛在費用。特定 Cloud Storage「資料夾」請務必查看:

  • console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/images
  • console.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com
  • 上方的儲存空間連結取決於您的 PROJECT_ID 和 *LOC*,例如「us」如果應用程式是由美國代管

另一方面,如果您不打算繼續使用這個應用程式或其他相關的遷移程式碼研究室,且想要徹底刪除所有項目,請關閉專案

本程式碼研究室的專屬功能

下列服務專屬於本程式碼研究室。詳情請參閱每項產品的說明文件:

後續步驟

我們會在單元 13 中介紹下一個要考慮的邏輯遷移作業,向開發人員說明如何從 App Engine memcache 服務遷移至 Cloud Memorystore。這些遷移全都可以自由選用,如果使用者想透過不同步驟翻新應用程式,可以自由選用。Cloud Memorystore 服務大幅升級到 App Engine 的 memcache,原因如下:

  • Cloud Memorystore 並非採用無伺服器技術。這表示您必須為快取分配伺服器。Cloud Memorystore 也未提供免費方案。這兩項因素都會對費用產生顯著影響。
  • Cloud Memorystore 支援兩種不同的基礎儲存空間機制 (快取引擎)、RedisMemcached
  • 相較於 App Engine Memcache,Cloud Memorystore (for Redis) 的功能組合更加豐富且深入。
  • 如要使用 Cloud Memorystore,您必須設定 Cloud Memorystore 伺服器並新增至 Google Cloud 虛擬私有雲網路,然後讓 App Engine 應用程式使用該網路與 Memorystore 伺服器通訊。

如果您覺得 Cloud Memorystore 的所有功能不需要用到,或是擔心這項服務對費用的影響,則可繼續使用 App Engine Memcache。

除了單元 13 外,也可以涵蓋其他可能的遷移作業,例如 Cloud NDB 和 Cloud Datastore 或 Cloud Tasks。還有產品跨產品遷移至 Cloud Run 和 Cloud Functions。您可以在遷移作業存放區找到上述所有項目。

另一個可行的步驟是移植至 Python 3,我們將在下一節中說明此階段的選擇性步驟。

7. BONUS:遷移至 Python 3

總覽

本節介紹的附加內容 (選用),將剛才完成的模組 12 應用程式遷移至 Python 3。我們先從設定開始,接著是應用程式

簡化 app.yaml

Python 3 執行階段的其中一項優點是可以大幅簡化 app.yaml

變更前:

以下是 app.yaml 單元 12 結論的內容:

runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: /.*
  script: main.app

由於 Python 3 執行階段需要網路架構自行轉送,因此 app.yaml 中的所有路徑處理常式都必須變更為 auto。如果沒有提供靜態檔案,使用者可以直接移除整個 handlers: 區段。此外,threadsafeapi_version 皆已淘汰

變更後:

完成上述必要變更之後,這是 Python 3 的替換 app.yaml

runtime: python39
app_engine_apis: true

唯一需要說明的行是 app_engine_apis: true。當舊版 App Engine 服務在 2021 年支援第二代執行階段後,某些執行階段 (包括 Python 3) 需要額外開機才能存取這些 API,例如 ndbtaskqueuememcache。而設定的這行程式碼就是這個目的。

更新 requirements.txt

requirements.txt 中需要另一個原始 API 的啟動程序:必須包含新的 App Engine SDK 存取權。

變更前:

以下是 app.yaml 單元 12 結論的內容:

flask

變更後:

只要新增 App Engine Python SDK,您應該會看到下列程式碼:

flask
appengine-python-standard

刪除 appengine_config.py 和 lib

新一代 App Engine 執行階段更新了第三方套件的使用方法:

  • 內建程式庫是指經過 Google 審核,且可在 App Engine 伺服器上使用的項目,原因可能是這些程式庫含有開發人員無法部署至雲端的 C/C++ 程式碼,第 2 代執行階段已無法使用。
  • 第 2 代執行階段不再需要複製非內建程式庫 (有時稱為「供應商」或「自行組合」)。應改為列在 requirements.txt 中,建構系統會在部署時自動代替您安裝。

也由於這些變更對第三方套件管理作業有所調整,因此您不需要使用 appengine_config.py 檔案和 lib 資料夾,因此請刪除這些資料夾。在第 2 代執行階段中,App Engine 會自動安裝 requirements.txt 中列出的第三方套件。總結:

  1. 沒有自行組合或複製的第三方程式庫;在「requirements.txt」中列出
  2. 沒有 pip install 放入 lib 資料夾,意味著沒有任何 lib 資料夾效期
  3. app.yaml 中沒有列出內建的第三方程式庫 (沒有 libraries 區段)。在「requirements.txt」中列出
  4. 沒有可從應用程式參照的第三方程式庫表示沒有任何 appengine_config.py 檔案

requirements.txt 中列出所有所需的第三方程式庫是唯一的開發人員規定。

更新應用程式以使用 App Engine SDK

如上所述,Python 3 應用程式需要進行一些修改,才能存取 App Engine 隨附的服務:

  1. 套裝組合 App Engine SDK (位於 requirements.txt)
  2. 啟用 App Engine SDK (在 app.yaml 中)
  3. 納入 WSGI 物件 (位於 main.py)

第一組已完成上方,因此最後一個要求是更新 main.py

變更前:

以下是單元 12 結尾的 Python 2 main.py

from flask import Flask, render_template, request
from google.appengine.api import memcache
from google.appengine.ext import ndb

app = Flask(__name__)
HOUR = 3600

變更後:

如果是 Python 3 通訊埠,請匯入 SDK 並與 Flask 應用程式物件包裝 (SDK 包裝函式),結果如下:

from flask import Flask, render_template, request
from google.appengine.api import memcache, wrap_wsgi_app
from google.appengine.ext import ndb

app = Flask(__name__)
app.wsgi_app = wrap_wsgi_app(app.wsgi_app)
HOUR = 3600

開發人員從 2.x 轉移至 3.x 時,必須對 Python 應用程式做出這些變更,才能存取套裝組合服務。如果您不是使用 Flask,也可參閱說明文件中的 Django 和 Pyramid 範例。如果您的 Python 2 程式碼不是網頁應用程式,只要在移植至 Python 3 時加入 SDK 套件即可。我們的應用程式程式碼原本就是為了在 Python 2 和 3 下運作,所以無需變更其他相容性。

部署應用程式

完成上述變更後,即可部署更新後的範例應用程式。(在同一個 GCP 專案中針對原始 Python 2 版本部署 Python 3 版本的應用程式沒有任何問題)。應用程式行為應維持不變。如果您需要比較新版應用程式與我們的資料,請參閱遷移存放區中的模組 12b 資料夾。如要進一步瞭解如何在 Python 3 等最新執行階段中支援 App Engine 套裝組合服務,請參閱功能推出公告單元 17 程式碼研究室

恭喜您完成單元 12 的額外步驟!另請參閱準備 Python 3 執行階段設定檔的說明文件。請參閱上方的「摘要/清除」一節,瞭解後續步驟及清除所用資源。

8. 其他資源

以下列出開發人員可進一步探索這個或相關的遷移模組和相關產品。包括提供這項內容意見回饋的地方、程式碼連結,以及各種實用的說明文件。

程式碼研究室問題/意見回饋

如果您在本程式碼研究室中發現任何問題,請先搜尋您的問題再提出申請。搜尋及建立新問題的連結:

遷移資源

下表提供模組 2 (START) 和單元 12 (FINISH) 的存放區資料夾連結。您也可以透過所有 App Engine 程式碼研究室遷移作業的存放區存取這些資料,可以複製或下載 ZIP 檔案。

Codelab

Python 2

Python 3

Module 1

程式碼

code (並未出現在本教學課程中)

單元 12 (本程式碼研究室)

程式碼

程式碼

線上參考資料

以下為可能與本教學課程相關的線上資源:

App Engine

Cloud Memorystore 和 Cloud Datastore

其他 Cloud 資訊

影片

授權

這項內容採用的是創用 CC 姓名標示 2.0 通用授權。