区域 ID
REGION_ID
是 Google 根据您在创建应用时选择的区域分配的缩写代码。此代码不对应于国家/地区或省,尽管某些区域 ID 可能类似于常用国家/地区代码和省代码。对于 2020 年 2 月以后创建的应用,REGION_ID.r
包含在 App Engine 网址中。对于在此日期之前创建的现有应用,网址中的区域 ID 是可选的。
详细了解区域 ID。
通过迁移或拆分流量来管理应用版本接收多少流量。
流量迁移可顺畅地切换请求路由,逐渐将流量从当前接收流量的版本迁移到您指定的一个或多个版本。
流量拆分可将一定比例的流量分配给应用的版本。您可以拆分流量以将全部流量迁移到单个版本,也可以将一定比例的流量路由到多个版本。通过将流量拆分到两个或更多版本,您可以在版本之间进行 A/B 测试,并控制新功能的推广步伐。
注意:流量拆分适用于未明确定位某个版本的网址。例如,以下网址之所以能够拆分流量,是因为它们定位指定服务中的所有可用版本:
[MY_PROJECT_ID].[REGION_ID].r.appspot.com
- 将流量分配给default
服务的各版本。[MY_SERVICE]-dot-[MY_PROJECT_ID].[REGION_ID].r.appspot.com
- 将流量分配给MY_SERVICE
服务的各版本。
REGION_ID
是 Google 根据您在创建应用时选择的区域分配的缩写代码。此代码不对应于国家/地区或省,尽管某些区域 ID 可能类似于常用国家/地区代码和省代码。对于 2020 年 2 月以后创建的应用,REGION_ID.r
包含在 App Engine 网址中。对于在此日期之前创建的现有应用,网址中的区域 ID 是可选的。
如需了解详情,请参阅请求的路由方式。
如需从 Google Cloud 控制台手动执行流量迁移和拆分,请参阅迁移流量和拆分流量。
准备工作
使用 Admin API 迁移流量的行为与 Google Cloud 控制台不同。要使用 Admin API 迁移流量,您必须能够授权 HTTP 请求,并且您的版本必须符合流量迁移要求:
流量迁移 (migrateTraffic=true
) 要求:
您的用户账号必须包含所需的权限,您才能配置流量。
App Engine 柔性环境不支持逐步迁移流量。
要逐步迁移流量,目标版本必须位于配置了以下功能的实例中:
- 预热请求
-
如需了解配置方面的信息,请参阅 app.yaml 参考文档。
迁移或拆分流量
要在您的应用版本之间迁移或拆分流量,请执行以下操作:
授权您的 HTTP 请求,例如获取访问令牌。
您可以使用不同的 OAuth 流程来完成 Admin API 的访问授权,具体取决于 API 应用的需求。如需了解详情,请参阅访问 API。
使用
apps.services
集合的patch
方法更新版本的配置,以迁移流量或配置流量拆分。以下示例 HTTPPATCH
请求已特意换行,旨在提高可读性:PATCH https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/ ?updateMask=split { "split": { "shardBy": "[MY_SHARDBY_METHOD]", "allocations": { "[MY_APP_VERSION]": [MY_TRAFFIC_PERCENT] } } }
HTTP 请求参数和字段:
updateMask
:指定配置中要更新的字段。migrateTraffic=true
(可选):指定逐步迁移流量。split
:定义版本的流量配置。shardBy
(可选):定义用于拆分流量的方法。对于逐步流量迁移 (migrateTraffic=true
) 是必需的。有效值为COOKIE
或IP
。allocations
:定义一个或多个版本以及分配给每个版本的流量百分比。版本和流量百分比以key:value
对形式指定。流量百分比以小数形式指定,总和必须为 1。示例:"allocations": { "v1": 0.8, "v2": 0.2 }
如需了解参数和字段的详情和完整列表,请参阅
apps.services
集合。示例 HTTP 请求:
将所有流量迁移到某个版本:
PATCH https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split {"split": { "allocations": { "v1": 1 } } }
将所有流量迁移到
v2
:PATCH https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split&migrateTraffic=true {"split": { "shardBy": "IP", "allocations": { "v2": 1 } } }
将 80% 的流量拆分到版本
v1
,将 20% 的流量拆分到v2
:PATCH https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split { "split": { "shardBy": "IP", "allocations": { "v1": 0.8, "v2": 0.2 } } }
示例:将流量迁移到另一个版本
此示例演示了如何将所有流量迁移到刚刚部署的新版本。例如,服务器返回错误,因此您修复了错误,部署了新的 v2
版本,现在想要重定向所有流量。
要将所有流量从 v1
迁移到 v2
,请执行以下操作:
使用
apps.services
集合的GET
方法验证目前所有流量都发送到v1
版本。示例 HTTP
GET
请求:GET https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default
示例 cURL 命令:
curl -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default
示例响应:
{ "name": "apps/[MY_PROJECT_ID]/services/default", "id": "default", "split": { "allocations": { "v1": 1 } } }
使用
apps.services
集合的PATCH
方法更新流量拆分配置,以将所有流量迁移到新版本。在 HTTP
PATCH
请求中,您必须指定同时运行两个版本的应用内服务,例如default
。您还必须添加具有split
值的updateMask
字段,以指定您要更新流量拆分配置。示例 HTTP
PATCH
请求:PATCH https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split {"split": { "allocations": { "v2": "1" } } }
示例 cURL 命令:
curl -X PATCH -H "Content-Type: application/json" -d "{ 'split': { 'allocations': { 'v2': '1' } } }" -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split
示例响应:
{ "name": "apps/[MY_PROJECT_ID]/operations/bdda402c-77a9-4c6d-b022-f2f69ba78420", "metadata": { "@type": "type.googleapis.com/google.appengine.v1.OperationMetadataV1", "insertTime": "2015-05-29T17:25:30.413Z", "method": "com.google.appengine.v1.Services.UpdateService", "target": "apps/[MY_PROJECT_ID]/services/default", "user": "me@example.com" } }
PATCH https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split&migrateTraffic=true {"split": { "shardBy": "IP", "allocations": { "v2": "1" } } }
确保配置更新已完成:
使用 HTTP
GET
请求查看更新操作的状态:要查看正在执行更新的操作的状态,请使用
apps.operations
集合的GET
方法以及上一步的 HTTP 响应中返回的操作name
:示例 HTTP
GET
请求:GET https://appengine.googleapis.com/v1/[OPERATION_NAME]
其中
[OPERATION_NAME]
是您在上一步发送的 HTTPPATCH
请求的响应中name
字段的值。如果上一步的 HTTP 响应包括:
"name": "apps/[MY_PROJECT_ID]/operations/bdda402c-77a9-4c6d-b022-f2f69ba78420"
然后发送以下 HTTP 请求以查看操作状态:
GET https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/operations/bdda402c-77a9-4c6d-b022-f2f69ba78420
示例 cURL 命令:
curl -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/operations/bdda402c-77a9-4c6d-b022-f2f69ba78420
操作完成后,您可以使用另一个 HTTP
GET
请求查看版本所在服务的详细信息:示例 HTTP
GET
请求:GET https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default
示例 cURL 命令:
curl -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default
可选:现在您可以通过 HTTP
DELETE
请求从 App Engine 应用中移除错误的v1
版本。示例 HTTP
DELETE
请求:DELETE https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/versions/v1
示例 cURL 命令:
curl -X DELETE -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/versions/v1
示例:在版本之间拆分流量
此示例演示了如何跨应用的多个版本配置流量拆分。例如,您刚刚创建了 v2
和 v3
版本,每个版本都包含新功能,但您希望逐步发布这些功能,使每个版本接收 20% 的流量。
将
v2
和v3
版本部署到 App Engine 应用后,您可以使用 HTTPPATCH
请求来配置这三个版本以进行流量拆分,使v1
接收 60% 的流量,v2
和v3
分别接收 20% 的流量:示例 HTTP
PATCH
请求:PATCH https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split { "split": { "shardBy": "IP", "allocations": { "v1": "0.6", "v2": "0.2", "v3": "0.2" } } }
示例 cURL 命令:
curl -X PATCH -H "Content-Type: application/json" -d "{ 'split': { 'shardBy': 'IP', 'allocations': { 'v1': '0.6', 'v2': '0.2', 'v3': '0.2' } } }" -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split
确认操作已完成后,您可以发送 HTTP
GET
请求来验证流量是否已在版本之间拆分,例如:示例 HTTP
PATCH
请求:GET https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default
示例 cURL 命令:
curl -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default
示例响应:
{ "name": "apps/[MY_PROJECT_ID]/services/default", "id": "default", "split": { "allocations": { "v1": 0.6, "v2": 0.2, "v3": 0.2 } } }