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

6분 분량
0

AWS SDK로 AWS Lambda 함수를 호출할 때 함수 제한 시간이 초과되거나, API 요청이 실패하거나, API 작업이 중복됩니다.

간략한 설명

다음과 같은 상황 때문에 AWS SDK로 Lambda 함수를 호출할 때 재시도 및 시간 초과 문제가 발생할 수 있습니다.

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

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

AWS SDK를 사용하여 API를 호출했는데 호출이 실패하면 AWS SDK가 자동으로 호출을 재시도합니다. AWS SDK가 재시도하는 횟수와 기간은 각 AWS SDK마다 다른 설정에 따라 결정됩니다.

기본 AWS SDK 재시도 설정

참고: 일부 값은 다른 AWS 서비스에서 다를 수 있습니다.

AWS SDK최대 재시도 횟수연결 시간 제한소켓 시간 제한
Python(Boto 3)서비스에 따라 다름60초60초
JavaScript/Node.js서비스에 따라 다름해당 없음120초
Java310초50초
.NET4100초300초
Go3해당 없음해당 없음

재시도 및 시간 초과 문제를 해결하려면 먼저 API 호출 로그를 검토하여 문제를 찾으십시오. 그런 다음 필요에 따라 각 사용 사례에 맞게 AWS SDK의 재시도 횟수 및 제한 시간 설정을 변경합니다. API 호출에 대한 응답에 충분한 시간을 허용하려면 Lambda 함수 제한 시간 설정에 시간을 추가하십시오.

해결 방법

AWS SDK에서 수행한 API 호출 로깅

Amazon CloudWatch Logs를 사용하여 연결 실패 및 각 연결 재시도 횟수에 대한 세부 정보를 얻을 수 있습니다. 자세한 내용은 Lambda에서 CloudWatch Logs 로그 사용을 참조하십시오. 또는 사용한 AWS SDK에 대한 다음 지침을 참조하십시오.

API 호출이 연결 설정에 실패한 오류 로그의 예(연결 시간 초과)

START RequestId: b81e56a9-90e0-11e8-bfa8-b9f44c99e76d Version: $LATEST2018-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

...

API 호출 연결에 성공했지만 API 응답이 너무 오래 걸려 제한 시간이 초과된 오류 로그의 예(소켓 시간 초과)

START RequestId: 3c0523f4-9650-11e8-bd98-0df3c5cf9bd8 Version: $LATEST2018-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 함수의 제한 시간 내에 응답을 받지 못하면 이러한 로그가 생성되지 않습니다. 함수 시간 초과로 인해 API 요청이 종료되는 경우 다음 중 하나를 시도해 보십시오.

AWS SDK의 설정 변경

AWS SDK의 재시도 횟수 및 제한 시간 설정은 API 호출이 응답을 받을 수 있는 충분한 시간을 허용해야 합니다. 각 설정에 적합한 값을 결정하려면 여러 구성을 테스트하고 다음 정보를 얻으십시오.

  • 성공적인 연결을 설정하는 데 걸리는 평균 시간
  • 전체 API 요청에 걸리는 평균 시간(성공적으로 반환될 때까지)

재시도 횟수 및 제한 시간 설정 변경에 대한 자세한 내용은 다음 AWS 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

    }

});

재시도 횟수 및 제한 시간 설정을 변경하는 JavaScript V3 명령의 예

const { S3Client, ListBucketsCommand } = require("@aws-sdk/client-s3");
const { NodeHttpHandler } = require("@aws-sdk/node-http-handler");
const client = new S3Client({
    requestHandler: new NodeHttpHandler({
        connectionTimeout: 30000,
        socketTimeout: 50000
    }),
    maxAttempts: 2
});

재시도 횟수 및 제한 시간 설정을 변경하는 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 호출이 응답을 받을 수 있는 충분한 시간을 허용하려면 함수 제한 시간 설정을 늘리십시오.

다음 공식을 사용하여 함수 제한 시간에 필요한 기본 시간을 추정할 수 있습니다.

First attempt (connection timeout + socket timeout) + Number of retries x (connection timeout + socket timeout) + 20 seconds additional code runtime margin = Required Lambda function timeout

Lambda 함수 제한 시간 계산의 예

참고: 다음은 세 번의 재시도, 10초의 연결 제한 시간, 30초의 소켓 제한 시간으로 구성된 AWS SDK에 대한 계산입니다.

First attempt (10 seconds + 30 seconds) + Number of retries [3 * (10 seconds + 30 seconds)] + 20 seconds additional code runtime margin = 180 seconds

관련 정보

호출

Lambda의 재시도 동작 이해

Lambda 할당량

AWS 공식
AWS 공식업데이트됨 6달 전