1. 概览
无服务器迁移站系列 Codelab(自定进度的实操教程)和相关视频旨在指导 Google Cloud 无服务器开发者完成一次或多次迁移(主要是从旧服务迁移),从而实现应用的现代化改造。这样做可以提高应用的可移植性,为您提供更多选择和灵活性,让您能够集成并访问更广泛的 Cloud 产品,并更轻松地升级到较新版本。虽然本系列最初主要面向的是最早接触 Cloud 的用户(主要是 App Engine(标准环境)开发者),但涵盖的范围非常广泛,涵盖了 Cloud Functions 和 Cloud Run 等其他无服务器平台,或其他无服务器平台(如适用)。
以前,开发者必须从 App Engine 的旧版“捆绑服务”进行迁移例如 Datastore 和 Memcache。通过在第 2 代 App Engine 服务中提供许多关键的捆绑服务,开发者现在可以将其应用移植到最新的运行时,同时继续使用(大部分)捆绑服务。此 Codelab 将引导您将示例应用从 Python 2 升级到 3,同时保持对 Datastore 捆绑服务的使用(通过 App Engine NDB 库)。大多数捆绑服务只需对代码进行细微更新(如本教程中所述),但还有一些服务需要进行更大范围的更改。我们将在“第 2 部分”中后续模块和 Codelab。
在接下来的实验中
- 将示例 App Engine 应用从 Python 2 移植到 3
- 更新应用配置以包含 App Engine SDK
- 将 SDK 代码添加到支持第二代运行时(例如 Python 3)中捆绑服务的应用
所需条件
- 具有活跃 GCP 结算账号的 Google Cloud 项目
- 基本 Python 技能
- 常用 Linux 命令的实践知识
- 具备开发和部署 App Engine 应用的基础知识
- 一个可正常运行的模块 1 App Engine 应用(建议完成相应 Codelab [推荐] 或从代码库中复制应用)
调查问卷
您将如何使用本教程?
您如何评价使用 Python 的体验?
您如何评价自己在使用 Google Cloud 服务方面的经验水平?
<ph type="x-smartling-placeholder">2. 背景
App Engine 原始服务于 2008 年推出,附带一组旧版 API(现在称为捆绑服务),以便开发者在全球范围内构建和部署应用。这些服务包括 Datastore、Memcache 和任务队列。虽然方便,但在使用专有 API 将其绑定到 App Engine 时,用户开始担心其应用的可移植性,并希望其应用的可移植性更高。再加上许多捆绑服务日渐成为独立的云产品,这促使 App Engine 团队在 2018 年推出了下一代平台,而没有这些服务。
Python 2 开发者急切地想要升级到 Python 3。使用捆绑式服务的 2.x 应用需要先从这些服务中迁出,然后才能移植到 3.x,这也代表了一系列强制连续迁移,可能也颇具挑战。为帮助实现这一转换,App Engine 团队在 2021 年秋季推出了“虫洞”可让下一代运行时上运行的应用访问众多捆绑式服务。虽然此版本不包含原始运行时中提供的所有服务,但主要播放器(如 Datastore、任务队列和 Memcache)仍然可用。
此 Codelab 演示了在将应用升级到 Python 3 的同时保留使用捆绑式服务的必要更改。我们的目标是让您的应用在最新的运行时上运行,这样您就可以按照自己的时间表从捆绑式服务迁移到 Cloud 独立服务或第三方替代方案,而不是阻碍 3.x 升级。虽然不再需要从捆绑式服务迁移,但这样做可以让您在托管应用程序的位置方面获得更多可移植性和灵活性,包括转移到可以更好地处理工作负载的平台,或者只是继续使用 App Engine,同时升级到更现代的语言版本(如前所述)。
第 1 单元的 Python 2 示例应用通过 App Engine NDB 使用 Datastore 捆绑服务。该应用已将框架从 webapp2 迁移到 Flask(已在第 1 单元 Codelab 中完成),但其 Datastore 用法保持不变。
本教程包含以下步骤:
- 设置/准备工作
- 更新配置
- 修改应用代码
3. 设置/准备工作
本节介绍如何执行以下操作:
- 设置 Cloud 项目
- 获取基准示例应用
- (重新)部署并验证基准应用
这些步骤可确保您从有效的代码开始。
1. 设置项目
如果您已完成第 1 单元的 Codelab,我们建议您重复使用同一项目(和代码)。您也可以新建一个 Cloud 项目,或重复使用其他现有项目。确保项目具有已启用 App Engine 服务的有效结算账号。
2. 获取基准示例应用
完成此 Codelab 的前提条件之一是具有有效的模块 1 App Engine 应用:完成模块 1 Codelab(推荐),或从代码库中复制模块 1 应用。无论您使用我们的代码还是我们的代码,我们都将从第 1 单元的代码开始。此 Codelab 将逐步引导您完成每个步骤,最后使用与模块 7 代码库文件夹“FINISH”中的代码类似的代码。
- START:Module 1 folder (Python 2)
- 完成:模块 1b 文件夹 (Python 3)
- 整个代码库(用于克隆或下载 ZIP 文件)
无论您使用哪个模块 1 应用,文件夹都应如下所示,可能还包含 lib
文件夹:
$ ls README.md appengine_config.py requirements.txt app.yaml main.py templates
3. (重新)部署基准应用
执行以下步骤(重新)部署模块 1 应用:
- 删除
lib
文件夹(如有),并运行pip install -t lib -r requirements.txt
以重新填充lib
。如果您同时安装了 Python 2 和 Python 3,则可能需要改用pip2
命令。 - 确保您已安装并初始化
gcloud
命令行工具并查看其使用情况。 - 如果您不希望在发出每个
gcloud
命令时都输入PROJECT_ID
,请使用gcloud config set project
PROJECT_ID
设置您的 Cloud 项目。 - 使用
gcloud app deploy
部署示例应用 - 确认模块 1 应用按预期运行,而不显示最近的访问记录(如下图所示)
4. 更新配置
成功执行这些步骤并看到您的 Web 应用正常运行后,您就可以将此应用移植到 Python 3 中(从 config 开始)。
将 SDK 添加到 requirements.txt
App Engine Python 3 运行时可显著降低使用第三方库的开销。只需在 requirements.txt
中列出它们即可。如需在 Python 3 中使用捆绑的服务,请向其中添加 App Engine SDK 软件包 appengine-python-standard
。SDK 软件包从模块 1 联接 Flask:
flask
appengine-python-standard
更新 app.yaml
请按照以下步骤将配置更改应用于 app.yaml
文件:
- 将
runtime
指令替换为受支持的 Python 3 版本;例如,对于 Python 3.10,指定python310
。 - 删除
threadsafe
和api_version
指令,因为这两个指令在 Python 3 中都未使用。 - 完全删除
handlers
部分,因为此应用只有脚本处理程序。如果您的应用具有静态文件处理程序,请在handlers
中保持不变。 - 与 Python 2 运行时不同,Python 3 运行时不支持内置第三方库。如果您的应用在
app.yaml
中有libraries
部分,请删除整个部分。(必需的软件包只需像非内置库一样在requirements.txt
中列出。)我们的示例应用没有libraries
部分,因此请转到下一步。 - 创建一个设置为
true
的app_engine_apis
指令以使用它,这对应于将 App Engine SDK 软件包添加到上面的requirements.txt
。
对 app.yaml
进行所需更改的摘要:
之前:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
之后:
runtime: python310
app_engine_apis: true
其他配置文件
由于所有第三方软件包都只需要在 requirements.txt
中列出,除非您在 appengine_config.py
中有特殊的软件包,否则不需要这些软件包,因此请将其删除。同样,由于所有第三方库都会在构建过程中自动安装,因此无需复制或提供它们,也就不再需要 pip install
命令和 lib
文件夹,因此请将其删除。总结:
- 删除
appengine_config.py
个文件 - 删除
lib
个文件夹
所有必要的配置更改到此结束。
5. 修改应用代码
访问 Python 3 运行时环境中大多数可用的捆绑式服务需要一小段代码,用于封装 main.py
中的网络服务器网关接口 (WSGI) 应用对象。封装容器函数是 google.appengine.api.wrap_wsgi_app()
,您可以通过导入该函数并使用该函数封装 WSGI 对象来使用它。进行以下更改,以反映 main.py
中 Flask 的必要更新:
之前:
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 wrap_wsgi_app
from google.appengine.ext import ndb
app = Flask(__name__)
app.wsgi_app = wrap_wsgi_app(app.wsgi_app)
如需查看其他 Python 框架的 WSGI 封装示例,请参阅文档。
尽管此示例使应用程序能够访问 Python 3 中的大多数捆绑服务,但 Blob 存储区和邮件等其他服务则需要额外的代码。我们将在另一个迁移单元中介绍这些示例。
本单元介绍将 App Engine 捆绑服务的使用添加到模块 1 示例应用的所有必要更改。该应用已经与 Python 2 和 3 兼容,因此除了您在配置中已完成的部分,无需进行其他更改即可将其移植到 Python 3。最后一步:将这个修改后的应用部署到下一代 App Engine Python 3 运行时,并确认更新成功。
6. 摘要/清理
在此 Codelab 的最后,本部分将部署应用,验证应用是否按预期以及任何反映的输出中正常运行。应用验证完成后,请执行所有清理操作,并考虑后续步骤。
部署并验证应用
使用 gcloud app deploy
部署 Python 3 应用,并确认该应用能像在 Python 2 中一样正常运行。所有功能均无变化,因此输出应与模块 1 应用相同:
最后说明
- 将您的现有资源与模块 1b 文件夹 (FINISH) 中的内容进行比较,如果您操作有误,并根据需要进行调整。
- 如果您的应用仍在使用
webapp2
,请对照此页面中的模块 0main.py
与模块 1bmain.py
,然后执行模块 1 Codelab,了解如何从webapp2
迁移到 Flask。
恭喜您迈出将 Python 2 App Engine 应用移植到 Python 3 的第一步,同时保留目前对捆绑式服务的使用。
清理
常规
如果您目前已完成,我们建议您停用 App Engine 应用,以免产生费用。不过,如果您希望测试或实验更多内容,App Engine 平台有免费配额,因此只要您不超过该使用量水平,您就不必支付费用。这只是计算费用,但相关 App Engine 服务可能也会产生费用,因此请查看其价格页面了解详情。如果此迁移涉及其他 Cloud 服务,这些服务单独计费。无论是哪种情况(如适用),请参阅“此 Codelab 的具体说明”部分。
为了全面披露,部署到像 App Engine 这样的 Google Cloud 无服务器计算平台会产生少量构建和存储费用。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
”。
另一方面,如果您不打算继续学习此应用或其他相关的迁移 Codelab,而是想彻底删除所有内容,请关停项目。
此 Codelab 的具体内容
下列服务是此 Codelab 独有的服务。有关详情,请参阅各个产品的文档:
- App Engine Datastore 服务由 Cloud Datastore(Datastore 模式的 Cloud Firestore)提供,该服务也有一个免费层级;如需了解详情,请参阅其价格页面。
后续步骤
从这里出发有以下几个方向:
- 使用需要更多代码更改的捆绑服务更新代码
- 从捆绑式服务迁移到 Cloud 独立产品
- 从 App Engine 迁移到另一个 Cloud 无服务器平台
访问其他捆绑服务(如 Blobstore、邮件和延迟)需要进行更多的代码更改。迁移模块主要是考虑弃用 App Engine 旧版捆绑式服务,包括:
- 第 2 单元:从 App Engine NDB 迁移到 Cloud NDB
- 模块 7-9:将 App Engine TaskQueue(推送任务)推送到 Cloud Tasks
- 模块 12-13:从 App Engine Memcache 迁移到 Cloud Memorystore
- 模块 15-16:从 App Engine Blob 存储区到 Cloud Storage
- 模块 18-19:将 App Engine 任务队列(拉取任务)添加到 Cloud Pub/Sub
App Engine 不再是 Google Cloud 中唯一的无服务器平台。如果您有一个小型 App Engine 应用或功能有限的应用,并希望将其转换为独立的微服务,或者您希望将单体式应用拆分为多个可重复使用的组件,那么这些都是考虑迁移到 Cloud Functions 的充分理由。如果容器化已成为应用开发工作流的一部分,特别是当它由 CI/CD(持续集成/持续交付或部署)流水线组成时,请考虑迁移到 Cloud Run。以下模块介绍了这些场景:
- 从 App Engine 迁移到 Cloud Functions:请参阅单元 11
- 从 App Engine 迁移到 Cloud Run:请参阅第 4 单元,了解如何使用 Docker 将应用容器化;请参阅第 5 单元,在不具备容器、Docker 知识或
Dockerfile
的情况下实现容器化
您可以自行选择是否切换到其他无服务器平台,我们建议您先考虑最适合您的应用和用例的方案,然后再做任何更改。
无论您接下来考虑使用哪种迁移模块,都可以通过其开源代码库访问所有 Serverless Migration Station 内容(Codelab、视频、源代码 [如果有])。代码库的 README
还提供了有关应考虑哪些迁移以及任何相关“顺序”的指南。迁移模块
7. 其他资源
下面列出的其他资源可帮助开发者进一步探索此迁移模块或相关迁移模块及相关产品。这包括提供有关此内容的反馈、代码链接以及各种可能对您有用的文档的地方。
Codelab 问题/反馈
如果您在此 Codelab 中发现任何问题,请先搜索您的问题,然后再提交。用于搜索和创建新问题的链接:
迁移时可参考的资源
下表列出了模块 1 (START) 和模块 1b (FINISH) 对应的代码库文件夹的链接。您还可以从所有 App Engine Codelab 迁移的代码库中访问这些代码库。
Codelab | Python 2 | Python 3 |
不适用 | ||
第 17 单元(此 Codelab) | 不适用 | 代码 (mod1b-flask) |
在线资源
以下是可能与本教程相关的在线资源:
App Engine 捆绑服务
- 在 Python 3 下一代运行时中访问捆绑服务
- 模块 0 应用 (Python 2) 与模块 1b 应用 (Python 3) 的并排比较
- App Engine SDK Web 框架 WSGI 对象封装容器示例
- 发布支持下一代运行时中的 App Engine 捆绑服务(2021 年)
App Engine 常规文档
- App Engine 文档
- Python 2 App Engine(标准环境)运行时
- 在 Python 2 App Engine 上使用 App Engine 内置库
- Python 3 App Engine(标准环境)运行时
- Python 2 与3 个 App Engine(标准环境)运行时
- Python 2 到 3 App Engine(标准环境)迁移指南
- App Engine 价格和配额信息
- 第二代 App Engine 平台发布(2018 年)
- 对旧版运行时的长期支持
- 文档迁移示例代码库
- 社区提供的迁移示例代码库
其他 Cloud 信息
- 在 Google Cloud Platform 上使用 Python 应用
- Google Cloud Python 客户端库
- Google Cloud“始终免费”计划层级
- Google Cloud SDK(
gcloud
命令行工具) - 所有 Google Cloud 文档
视频
许可
此作品已获得 Creative Commons Attribution 2.0 通用许可授权。