Admin API로 트래픽 마이그레이션 및 분할

리전 ID

REGION_ID는 앱을 만들 때 선택한 리전을 기준으로 Google에서 할당하는 축약된 코드입니다. 일부 리전 ID는 일반적으로 사용되는 국가 및 주/도 코드와 비슷하게 표시될 수 있지만 코드는 국가 또는 주/도와 일치하지 않습니다. 2020년 2월 이후에 생성된 앱의 경우 REGION_ID.r이 App Engine URL에 포함됩니다. 이 날짜 이전에 만든 기존 앱의 경우 URL에서 리전 ID는 선택사항입니다.

리전 ID에 대해 자세히 알아보세요.

트래픽을 마이그레이션하거나 분할하여 애플리케이션 버전에서 수신하는 트래픽 양을 관리합니다.

트래픽 이전은 요청 라우팅을 원활하게 전환하여, 트래픽을 현재 수신 중인 버전에서 사용자가 지정하는 하나 이상의 버전으로 점진적으로 이동합니다.

트래픽 분할은 트래픽의 비율을 여러 애플리케이션 버전에 분할합니다. 트래픽을 분할하여 트래픽의 100%를 단일 버전으로 이동하거나 일정한 비율의 트래픽을 여러 버전으로 라우팅할 수 있습니다. 트래픽을 두 개 이상의 버전으로 분할하면 서로 다른 버전 간에 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 Console에서 트래픽 마이그레이션과 분할을 수동으로 수행하려면 트래픽 마이그레이션트래픽 분할을 참조하세요.

시작하기 전에

Admin API를 사용한 트래픽 마이그레이션은 Google Cloud Console에서의 마이그레이션과 다르게 동작합니다. 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: 하나 이상의 버전과 각 버전으로 분산되는 트래픽 비율을 정의합니다. 트래픽의 버전 및 비율은 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 메서드를 사용하여 현재 트래픽의 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). 또한 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 요청을 사용하여 업데이트 작업의 상태를 봅니다.

      업데이트를 수행하는 작업의 상태를 보려면 이전 단계의 HTTP 응답에서 반환된 name 작업과 함께 apps.operations 컬렉션GET 메서드를 사용합니다.

      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 애플리케이션에 배포한 후 트래픽이 v1에 60%, v2v3에 각각 20%씩 분할되도록 HTTP PATCH 요청을 사용하여 세 버전을 구성합니다.

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