Admin API でトラフィックの移行と分割を行う

リージョン ID

REGION_ID は、アプリの作成時に選択したリージョンに基づいて Google が割り当てる省略形のコードです。一部のリージョン ID は、一般的に使用されている国や州のコードと類似しているように見える場合がありますが、このコードは国または州に対応するものではありません。2020 年 2 月以降に作成されたアプリの場合、REGION_ID.r は App Engine の URL に含まれています。この日付より前に作成されたアプリの場合、URL のリージョン ID は省略可能です。

詳しくは、リージョン ID をご覧ください。

トラフィックを移行または分割することにより、アプリケーションのバージョンが受信するトラフィックの量を管理します。

トラフィック移行を行うと、リクエストのルーティングが徐々に切り替わり、トラフィックを現在受信しているバージョンから指定された 1 つ以上のバージョンにトラフィックが段階的に移行されます。

トラフィック分割を行うと、指定したパーセンテージでトラフィックをアプリケーションのバージョンに分散します。トラフィック分割により、トラフィックの 100% を 1 つのバージョンに移行したり、指定した割合のトラフィックを複数のバージョンにルーティングしたりできます。トラフィックを 2 つ以上のバージョンに分割すると、バージョン間で A/B テストを実施して、機能をロールアウトする際のペースを制御できます。

トラフィック分割は、ターゲットとなるバージョンを明示的に指定していない URL に適用されます。たとえば、次の URL は、指定されたサービス内の使用可能なすべてのバージョンをターゲットとしているので、トラフィックが分割されます。

  • [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 の URL に含まれています。この日付より前に作成された既存のアプリの場合、URL のリージョン ID は省略可能です。

詳細については、リクエストのルーティング方法をご覧ください。

Google Cloud コンソールから手動でトラフィックの移行と分割を行う方法については、トラフィックの移行トラフィックの分割をご覧ください。

始める前に

Admin API によるトラフィック移行の動作は、Google Cloud コンソールとは異なります。Admin API でトラフィックを移行するには、HTTP リクエストの承認が可能で、バージョンがトラフィック移行の要件を満たしていることが必要です。

トラフィック移行(migrateTraffic=true)の要件:

  • トラフィックを構成するには、ユーザー アカウントに必要な権限が含まれている必要があります。

  • 段階的なトラフィック移行は、App Engine フレキシブル環境でサポートされていません。

  • 段階的なトラフィック移行を行うには、以下が構成されているインスタンス内にターゲット バージョンが配置されている必要があります。

トラフィックの移行または分割

アプリのバージョン間でトラフィックを移行または分割するには:

  1. アクセス トークンの取得など、HTTP リクエストを承認します。

    Admin API へのアクセスの承認は、API アプリのニーズに応じてさまざまな OAuth フローを使用して行うことができます。詳細については、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)。有効な値は COOKIE または IP です。
      • allocations: 1 つ以上のバージョンと、各バージョンに分散するトラフィックのパーセンテージを定義します。トラフィックのバージョンとパーセンテージは、key:value ペアとして指定します。トラフィックのパーセンテージは小数で指定し、合計が 1 になるようにします。例: "allocations": { "v1": 0.8, "v2": 0.2 }

    パラメータとフィールドの詳細については、apps.services コレクションをご覧ください。

    HTTP リクエストの例:

    • すべてのトラフィックを 1 つのバージョンに移行する:

      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 メソッドを使用して、現在、トラフィックの 100% が 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)を指定する必要があります。また、トラフィック分割の構成の更新を行うことを指定するには、updateMask フィールドに split 値を含める必要があります。

    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 リクエストにより、不具合のある v1 バージョンを App Engine アプリケーションから削除できるようになりました。

    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 リクエストを使用して、トラフィックの 60% が v1 に、20% がそれぞれ v2v3 に分割されるように 3 つのバージョンを構成します。

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