使用 Admin API 迁移和拆分流量

区域 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 柔性环境不支持逐步迁移流量。

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

迁移或拆分流量

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

  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"
      }
    }
    
    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
    

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

此示例演示了如何跨应用的多个版本配置流量拆分。例如,您刚刚创建了 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
        }
      }
    }