멱등성(idempotency) 보장하기

멱등성(idempotency) 보장하기

변경(mutating) 작업을 수행하면, 리소스가 변경된 후 발생하는 타임아웃이나 서버 문제로 인해 예외를 볼 수 있어요. 이로 인해 변경이 발생했는지 판단하기 어려워질 수 있고 여러 번의 재시도로 이어질 수 있습니다. 하지만 원래 작업과 후속 재시도가 실제로 변경을 수행했다면, 중첩된 변경을 적용하거나 의도보다 더 많은 리소스를 만들 수 있습니다.

출처: 문서

본문

변경 작업을 수행할 때, 리소스가 변경된 뒤에 발생하는 타임아웃이나 서버 문제로 예외가 나타날 수 있습니다. 이는 변경이 발생했는지 판단하기 어렵게 만들고 여러 번의 재시도를 초래할 수 있어요. 그러나 원래 작업과 후속 재시도가 실제로 변경을 수행했다면, 변경 사항이 중첩되거나 의도보다 더 많은 리소스가 만들어질 수 있습니다. 멱등성은 작업이 리소스를 두 번 이상 변경하지 않도록 보장합니다. 멱등 요청으로 원래 요청이 성공적으로 변경되었다면, 이후의 재시도는 더 이상의 변경 없이 성공적으로 완료됩니다.

주제: Amazon ECS의 멱등성 / RunTask의 멱등성 / 예제 / 멱등 요청의 재시도 권장 사항

Amazon ECS의 멱등성

다음 API 작업들은 클라이언트 토큰(client token)을 사용한 멱등성을 선택적으로 지원합니다. 해당 AWS CLI 명령들도 클라이언트 토큰을 사용한 멱등성을 지원합니다. 클라이언트 토큰은 고유하고 대소문자를 구분하는 문자열입니다. 이 작업 중 하나로 멱등 API 요청을 하려면 요청에 클라이언트 토큰을 지정하세요. 같은 클라이언트 토큰을 다른 API 요청에 재사용하면 안 됩니다. 성공적으로 완료된 요청을 같은 클라이언트 토큰과 같은 파라미터로 재시도하면, 재시도는 추가 작업 없이 성공합니다.

클라이언트 토큰으로 멱등 실행하는 작업

  • CreateService — 클라이언트 토큰은 33~126(포함) 범위의 ASCII 문자 최대 36자.
  • CreateTaskSet — 클라이언트 토큰은 33~126(포함) 범위의 ASCII 문자 최대 36자.
  • RunTask — 클라이언트 토큰은 33~126(포함) 범위의 ASCII 문자 최대 64자.

멱등성 유형

  • cluster – 같은 클러스터에서 같은 토큰을 가진 요청은 멱등입니다. 예를 들어 ClientToken A는 Cluster X에서 RunTask 요청의 요청 파라미터로 한 번만 사용될 수 있습니다. 다른 클러스터로의 RunTask 요청은 별개의 요청으로 간주되므로, Cluster Y의 RunTask 요청에는 ClientToken A를 사용할 수 있어요.

RunTask의 멱등성

RunTask API는 클라이언트 토큰을 사용한 멱등성을 지원합니다. 클라이언트 토큰은 API 요청을 할 때 지정하는 고유 문자열입니다. 성공적으로 완료된 후 같은 클라이언트 토큰과 같은 요청 파라미터로 API 요청을 재시도하면 원래 요청의 결과가 반환됩니다. 성공한 요청을 같은 클라이언트 토큰으로 재시도하지만 Region이나 Availability Zone을 제외한 파라미터가 하나 이상 다르면, 재시도는 ConflictException으로 실패합니다. 클라이언트 토큰을 직접 지정하지 않으면 AWS SDK와 AWS Command Line Interface가 요청이 멱등하도록 자동으로 클라이언트 토큰을 생성합니다. 클라이언트 토큰은 33~126(포함) 범위의 ASCII 문자 최대 64자를 포함하는 모든 문자열일 수 있습니다.

RunTask 클라이언트 토큰의 TTL(time to live)은 24시간입니다. 같은 클라이언트 토큰을 다른 요청에 재사용하면 안 됩니다. 클라이언트 토큰의 최대 TTL은 다음 두 값 중 더 낮은 값으로 유효합니다.

  • 24시간
  • 리소스 수명 + 1시간

리소스의 수명은 태스크가 생성된 타임스탬프부터 마지막 상태(lastStatus)가 STOPPED로 전환된 타임스탬프까지입니다. RunTask로 둘 이상의 태스크를 시작할 때, 리소스 수명은 STOPPED로 전환된 마지막 태스크의 수명과 같습니다.

RunTask 재시도 규칙과 응답

5xx 예외를 받아 요청을 재시도하면, 재시도된 성공 응답은 일반적으로 원래 요청이 반환했을 모든 정보를 포함합니다. 한 시간 미만 동안 중지된 태스크는 태스크 ARN, 마지막 상태, desired status만 포함합니다.

다음은 실행 중인 태스크 하나, 중지된 태스크 하나, 시작에 실패한 태스크 하나가 있을 때 재시도의 응답 예제 조각입니다.

{
  "failures": [
    {
      "arn": "arn:aws:ecs:us-east-1:123456789012:container/4df26bb4-f057-467b-a079-961675296e64",
      "reason": "RESOURCE:MEMORY"
    }
  ],
  "tasks": [
    {
      "desiredStatus": "RUNNING",
      "taskArn": "arn:aws:ecs:us-east-1:123456789012:task/default/fdf2c302-468c-4e55-b884-5331d816e7fb",
      ...
    },
    {
      "taskArn": "arn:aws:ecs:us-east-1:123456789012:task/default/fdf2c302-468c-4e55-b884-5331d819999",
      "lastStatus": "STOPPED",
      ...
     }
  ]
}

한 시간이 넘은 실패(failures)는 실패한 태스크 수만 포함합니다.

예제

AWS CLI 명령 예제

AWS CLI 명령을 멱등으로 만들려면 --client-token 옵션을 추가하세요.

예: create-service — 다음 create-service 명령은 클라이언트 토큰을 포함하므로 멱등성을 사용합니다.

aws ecs create-service \
   --cluster MyCluster \
   --service MyService \
   --task-definition MyTaskDefinition:2 \
   --desired-count 2 \
   --launch-type FARGATE \
   --platform-version LATEST \
   --network-configuration "awsvpcConfiguration={subnets=["subnet-12344321"],securityGroups=["sg-12344321"],assignPublicIp="ENABLED"}" \
   --client-token 550e8400-e29b-41d4-a716-44665544

예: create-task-set — 다음 create-task-set 명령은 클라이언트 토큰을 포함하므로 멱등성을 사용합니다.

aws ecs create-task-set \
   --cluster MyCluster \
   --service MyService \
   --task-definition MyTaskDefinition:2 \
   --network-configuration "awsvpcConfiguration={subnets=["subnet-12344321"],securityGroups=["sg-12344321"]}" \
   --client-token 550e8400-e29b-41d4-a716-44665544

예: run-task — 다음 run-task 명령은 클라이언트 토큰을 포함하므로 멱등성을 사용합니다.

aws ecs run-task \
   --cluster MyCluster \
   --task-definition MyTaskDefinition:2 \
   --client-token 550e8400-e29b-41d4-a716-446655440000

API 요청 예제

API 요청을 멱등으로 만들려면 clientToken 파라미터를 추가하세요.

예: CreateService — 다음 CreateService API 요청은 클라이언트 토큰을 포함하므로 멱등성을 사용합니다.

POST / HTTP/1.1
Host: ecs.us-east-1.amazonaws.com
Accept-Encoding: identity
Content-Length: 87
X-Amz-Target: AmazonEC2ContainerServiceV20141113.CreateService
X-Amz-Date: 20150429T170125Z
Content-Type: application/x-amz-json-1.1
Authorization: AUTHPARAMS
***
{
  "serviceName": "MyService",
  "taskDefinition": "MyTaskDefinition:2",
  "desiredCount": 10,
   "capacityProviderStrategy": [ 
      { 
         "base": "number",
         "capacityProvider": "FARGATE",
         "weight": 1
      }
   ],
   "capacityProviderStrategy": [ 
      { 
         "base": "number",
         "capacityProvider": "FARGATE_SPOT",
         "weight": 1
      }
   ],
   "clientToken": "550e8400-e29b-41d4-a716-44665544"
}

예: CreateTaskSet — 다음 CreateTaskSet API 요청은 클라이언트 토큰을 포함하므로 멱등성을 사용합니다.

POST / HTTP/1.1
Host: ecs.us-east-1.amazonaws.com
Accept-Encoding: identity
Content-Length: 87
X-Amz-Target: AmazonEC2ContainerServiceV20141113.CreateTaskSet
X-Amz-Date: 20150429T170125Z
Content-Type: application/x-amz-json-1.1
Authorization: AUTHPARAMS
***
{
  "serviceName": "MyService",
  "taskDefinition": "mytask:1",
  "desiredCount": 1,
   "capacityProviderStrategy": [ 
      { 
         "base": "number",
         "capacityProvider": "FARGATE",
         "weight": 1
      }
   ],
   "capacityProviderStrategy": [ 
      { 
         "base": "number",
         "capacityProvider": "FARGATE_SPOT",
         "weight": 1
      }
   ],
    "clientToken": "550e8400-e29b-41d4-a716-44665544" 
}

예: RunTask — 다음 RunTask API 요청은 클라이언트 토큰을 포함하므로 멱등성을 사용합니다.

POST / HTTP/1.1
Host: ecs.us-east-1.amazonaws.com
Accept-Encoding: identity
Content-Length: 45
X-Amz-Target: AmazonEC2ContainerServiceV20141113.RunTask
X-Amz-Date: 20161121T215740Z
User-Agent: aws-cli/1.11.13 Python/2.7.12 Darwin/16.1.0 botocore/1.4.66
Content-Type: application/x-amz-json-1.1
Authorization: AUTHPARAMS
***
{
  "count": 1,
  "taskDefinition": "mytask:1",
  "clientToken": "550e8400-e29b-41d4-a716-446655440000" 
}

멱등 요청의 재시도 권장 사항

다음 표는 멱등 API 요청에 대해 받을 수 있는 일반적인 응답과 재시도 권장 사항을 보여줍니다.

응답 권장 사항 설명
200 (OK) 재시도하지 않음 원래 요청이 성공적으로 완료되었습니다. 이후의 재시도는 성공적으로 반환됩니다.
400 시리즈 응답 코드(클라이언트 오류) 재시도하지 않음 다음 중 하나에 해당하는 요청 문제가 있습니다.
• 유효하지 않은 파라미터 또는 파라미터 조합을 포함합니다.
• 권한이 없는 작업이나 리소스를 사용합니다.
• 상태가 변경 중인 리소스를 사용합니다.
요청이 상태 변경 중인 리소스와 관련된 경우, 재시도하면 성공할 수 있습니다.
500 시리즈 응답 코드(서버 오류) 재시도 오류가 AWS 서버 측 문제로 발생했으며 일반적으로 일시적입니다. 적절한 back-off 전략으로 요청을 반복하세요.

더 알아보기 (Learn more)

  • 멱등성과 클라이언트 토큰에 대한 자세한 내용은 AWS 공식 문서를 참고해 주세요.