AWS SDK를 사용하여 Lambda 함수를 호출할 때 재시도 및 시간 초과 문제가 발생할 경우 어떻게 해결합니까?

최종 업데이트 날짜: 2020년 5월 28일

AWS SDK를 사용하여 AWS Lambda 함수를 호출하려고 하면 함수 시간 초과가 발생하고 함수 실행이 중단되거나, API 작업이 중복됩니다. 이러한 문제를 해결하려면 어떻게 해야 합니까?

간략한 설명

이러한 문제는 다음과 같은 경우에 발생할 수 있습니다.

  • 응답하는 데 너무 오래 걸리거나 연결할 수 없는 원격 API를 호출한 경우
  • API 호출이 소켓 제한 시간 내에 응답을 받지 못하는 경우
  • API 호출이 Lambda 함수의 제한 시간 내에 응답을 받지 못하는 경우

참고: 네트워크 연결 문제가 발생할 경우 API 호출이 예상보다 더 오래 걸릴 수 있습니다. 또한 네트워크 문제로 인해 재시도 및 중복 API 요청이 발생할 수도 있습니다. 이러한 상황에 대비하려면 Lambda 함수가 항상 멱등성이어야 합니다.

AWS SDK를 사용하여 API 호출을 수행했는데 호출이 실패하는 경우 SDK에서 자동으로 호출을 다시 시도합니다. SDK의 API 호출 재시도 기간 및 횟수는 지정된 설정에 따라 결정되며, 해당 설정은 SDK마다 다릅니다. 다음은 이러한 설정의 기본값입니다.

참고: 특정 AWS 서비스의 경우 일부 값이 다를 수 있습니다.

AWS SDK Maximum retry count(최대 재시도 횟수) Connection timeout(연결 제한 시간) Socket timeout(소켓 제한 시간)
Python(Boto 3) 서비스에 따라 다름 60초 60초
JavaScript/Node.js 서비스에 따라 다름 해당 사항 없음 120초
Java 3 10초 50초
.NET 4 100초 300초
Go 3 해당 사항 없음 해당 사항 없음

재시도 및 시간 초과 문제를 해결하려면 API 호출 로그를 검토하여 문제점을 찾습니다. 그런 다음, 각 사용 사례별로 필요에 따라 SDK의 재시도 횟수 및 제한 시간 설정을 변경합니다. API 호출에 대한 응답에 충분한 시간을 허용하려면 Lambda function timeout setting(Lambda 함수 제한 시간 설정)에 시간을 추가합니다.

해결 방법

SDK에서 수행한 API 호출 로깅

Amazon CloudWatch Logs를 사용하면 실패한 연결 및 시도한 재시도 횟수에 대한 세부 정보를 확인할 수 있습니다. 자세한 내용은 AWS Lambda에 대한 Amazon CloudWatch logs에 액세스를 참조하십시오. 또는 사용 중인 SDK에 대한 다음 지침을 참조하십시오.

이 오류 로그 예제에서는 API 호출이 연결을 설정하지 못했습니다(소켓 시간 초과).

START RequestId: b81e56a9-90e0-11e8-bfa8-b9f44c99e76d Version: $LATEST
2018-07-26T14:32:27.393Z    b81e56a9-90e0-11e8-bfa8-b9f44c99e76d    [AWS ec2 undefined 40.29s 3 retries] describeInstances({})
2018-07-26T14:32:27.393Z    b81e56a9-90e0-11e8-bfa8-b9f44c99e76d    { TimeoutError: Socket timed out without establishing a connection

...

이 오류 로그 예제에서는 연결이 성공했지만 응답 시간이 너무 오래 걸려서 제한 시간이 초과되었습니다(연결 시간 초과).

START RequestId: 3c0523f4-9650-11e8-bd98-0df3c5cf9bd8 Version: $LATEST
2018-08-02T12:33:18.958Z    3c0523f4-9650-11e8-bd98-0df3c5cf9bd8    [AWS ec2 undefined 30.596s 3 retries] describeInstances({})
2018-08-02T12:33:18.978Z    3c0523f4-9650-11e8-bd98-0df3c5cf9bd8    { TimeoutError: Connection timed out after 30s

참고: API 호출이 Lambda 함수의 제한 시간 내에 응답을 받지 못하면 이러한 로그가 생성되지 않습니다. 함수 제한 시간으로 인해 실행이 종료되면 다음 중 하나를 수행합니다.

  • 모든 재시도가 제한 시간 내에 수행되도록 SDK의 재시도 설정을 변경합니다.
  • 일시적으로 Lambda 함수 제한 시간 설정을 늘려 SDK 로그 생성에 충분한 시간을 허용합니다.

SDK 설정 변경

SDK의 재시도 횟수 및 제한 시간 설정에서 API 호출이 응답을 받는 데 충분한 시간을 허용해야 합니다. 각 설정에 대해 적절한 값을 결정하려면 다양한 구성을 테스트하고 다음 정보를 얻어야 합니다.

  • 성공적인 연결을 설정하는 데 걸린 평균 시간
  • 전체 API 요청에 소요된(성공적으로 반환될 때까지) 평균 시간
  • SDK 또는 코드에서 재시도해야 하는지 여부

이러한 설정을 변경하는 방법에 대한 자세한 내용은 SDK 클라이언트 구성 설명서를 참조하십시오.

다음은 각 런타임에 대해 이러한 설정을 변경하는 방법의 예입니다.

참고: 다음 예제 명령을 사용하려면 먼저, 각 설정의 예제 값을 사용 사례의 해당 값으로 바꿉니다.

Python(Boto 3) 예:

# max_attempts: retry count / read_timeout: socket timeout / connect_timeout: new connection timeout

from botocore.session import Session
from botocore.config import Config

s = Session()
c = s.create_client('s3', config=Config(connect_timeout=5, read_timeout=60, retries={'max_attempts': 2}))

JavaScript/Node.js 예:

// maxRetries: retry count / timeout: socket timeout / connectTimeout: new connection timeout

var AWS = require('aws-sdk');

AWS.config.update({

    maxRetries: 2,

    httpOptions: {

        timeout: 30000,

        connectTimeout: 5000

    }

});

Java 예:

// setMaxErrorRetry(): retry count / setSocketTimeout(): socket timeout / setConnectionTimeout(): new connection timeout

ClientConfiguration clientConfig = new ClientConfiguration(); 

clientConfig.setSocketTimeout(60000); 
clientConfig.setConnectionTimeout(5000);
clientConfig.setMaxErrorRetry(2);

AmazonDynamoDBClient ddb = new AmazonDynamoDBClient(credentialsProvider,clientConfig);

.NET 예:

// MaxErrorRetry: retry count / ReadWriteTimeout: socket timeout / Timeout: new connection timeout

var client = new AmazonS3Client(

    new AmazonS3Config {
        Timeout = TimeSpan.FromSeconds(5),
        ReadWriteTimeout = TimeSpan.FromSeconds(60),
        MaxErrorRetry = 2
});

재시도 횟수에 대한 Go 예:

// Create Session with MaxRetry configuration to be shared by multiple service clients.
sess := session.Must(session.NewSession(&aws.Config{
    MaxRetries: aws.Int(3),
}))
 
// Create S3 service client with a specific Region.
svc := s3.New(sess, &aws.Config{
    Region: aws.String("us-west-2"),
}) 

요청 시간 초과에 대한 Go 예:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// SQS ReceiveMessage
params := &sqs.ReceiveMessageInput{ ... }
req, resp := s.ReceiveMessageRequest(params)
req.HTTPRequest = req.HTTPRequest.WithContext(ctx)
err := req.Send()

(선택 사항) Lambda 함수의 제한 시간 설정 변경

Lambda 함수 제한 시간 값이 낮으면 정상적인 연결이 너무 일찍 중단될 수 있습니다. 사용 사례에서 이런 상황이 발생하는 경우 함수 제한 시간 설정 설정을 늘려서 API 호출이 응답을 받는 데 충분한 시간을 허용해야 합니다. 이 공식을 사용하여 함수 제한 시간에 필요한 기본 시간을 계산할 수 있습니다.

Retries * (Connection timeout + Socket timeout)

예를 들어 SDK가 3회 재시도, 10초 연결 제한 시간 및 30초 소켓 제한 시간으로 구성되어 있다고 가정합니다. 이 경우 Lambda 함수 제한 시간은 120초 이상이어야 합니다.

3 * (10 + 30) = 120 seconds

나머지 코드 실행을 처리하기 위해 여유 시간(예: 20초)을 더 추가합니다.

120 + 20 = 140 seconds

이 문서가 도움이 되었습니까?

AWS에서 개선해야 할 부분이 있습니까?


도움이 필요하십니까?