使用 Admin API 迁移和拆分流量

地区 ID

REGION_ID 是 Google 根据您在创建应用时选择的地区分配的缩写代码。此代码不对应于国家/地区或省,尽管某些地区 ID 可能类似于常用国家/地区代码和省代码。在 App Engine 网址中包含 REGION_ID.r 对于现有应用是可选项,但在不久后将成为所有新应用的必要项。

为了确保顺利过渡,我们正在逐步更新 App Engine 以使用地区 ID。如果我们尚未更新您的 Google Cloud 项目,则您不会看到应用的区域 ID。由于该 ID 对于现有应用是可选的,因此您在现有应用可以使用区域 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 可能类似于常用国家/地区代码和省代码。在 App Engine 网址中包含 REGION_ID.r 对于现有应用是可选项,但在不久后将成为所有新应用的必要项。

为了确保顺利过渡,我们正在逐步更新 App Engine 以使用地区 ID。如果我们尚未更新您的 Google Cloud 项目,则您不会看到应用的区域 ID。由于该 ID 对于现有应用是可选的,因此您在现有应用可以使用区域 ID 后无需更新网址或进行其他更改。

如需了解详情,请参阅请求的路由方式

如需从 Cloud Console 手动执行流量迁移和拆分,请参阅迁移流量拆分流量

准备工作

使用 Admin API 迁移流量的行为与 Cloud Console 不同。要使用 Admin API 迁移流量,您必须能够授权 HTTP 请求,并且您的版本必须符合流量迁移要求:

流量迁移 (migrateTraffic=true) 要求

  • 您的用户帐号必须包含所需的权限,您才能配置流量。

  • App Engine 柔性环境不支持逐步迁移流量。

  • 要逐步迁移流量,目标版本必须位于配置了以下功能的实例中:

迁移或拆分流量

要在您的应用版本之间迁移或拆分流量,请执行以下操作:

  1. 授权您的 HTTP 请求,例如获取访问令牌。

    您可以使用不同的 OAuth 流程来完成 Admin API 的访问授权,具体取决于 API 应用的需求。如需了解详情,请参阅访问 API

  2. 使用 apps.services 集合patch 方法更新版本的配置,以迁移流量或配置流量拆分。以下示例 HTTP PATCH 请求已特意换行,旨在提高可读性:

    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) 是必需的。有效值为 COOKIEIP
      • 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,请执行以下操作:

  1. 使用 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
        }
      }
    }
    
  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"
      }
    }
    

    提示:上面的 HTTP PATCH 请求会立即将流量迁移到 v2 版本。如果要以逐步重新路由的方式迁移流量,您必须指定 migrateTraffic=true 参数并包含 shardBy 字段,例如:

    PATCH https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split&migrateTraffic=true {"split": { "shardBy": "IP", "allocations": { "v2": "1" } } }
    
  2. 确保配置更新已完成:

    1. 使用 HTTP GET 请求查看更新操作的状态:

      要查看正在执行更新的操作的状态,请使用 apps.operations 集合GET 方法以及上一步的 HTTP 响应中返回的操作 name

      示例 HTTP GET 请求:

      GET https://appengine.googleapis.com/v1/[OPERATION_NAME]
      

      其中 [OPERATION_NAME] 是您在上一步发送的 HTTP PATCH 请求的响应中 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
      
    2. 操作完成后,您可以使用另一个 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
      
  3. 可选:现在您可以通过 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
    

    提示:您可以运行 HTTP GET 请求来验证操作是否成功,一个请求用于验证删除操作是否已完成,另一个请求用于验证版本是否已删除。

示例:在版本之间拆分流量

此示例演示了如何跨应用的多个版本配置流量拆分。例如,您刚刚创建了 v2v3 版本,每个版本都包含新功能,但您希望逐步发布这些功能,使每个版本接收 20% 的流量。

  1. v2v3 版本部署到 App Engine 应用后,您可以使用 HTTP PATCH 请求来配置这三个版本以进行流量拆分,使 v1 接收 60% 的流量,v2v3 分别接收 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
    
  2. 确认操作已完成后,您可以发送 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
        }
      }
    }