6. Graceful Error Handling
람다 서비스에서 돌아가는 코드는 다양한 실행 오류에 직면할 수 있다. 람다 서비스가 다른 서비스와 통합되는 방식은 3가지가 있는데, 각 방식에 맞추어 에러를 처리하는 방식도 달라진다.
- Sync
- 동기적인 워크플로의 대표적인 구성 예는 API Gateway를 이벤트 소스로 두는 경우이다. API Gateway는 람다 서비스에 어떤 요청을 전송할 뿐만 아니라 대응하는 응답의 반환을 기다린다.
- 따라서 람다 실행 중에 에러가 발생했다면 이를 훌륭하게 묘사하는 예외 응답을 내려주어야 한다.
- Async
- 람다를 호출하고 잊어버리는 모든 워크플로가 이 유형이다. 람다 실행 중에 에러가 발생하면 클라이언트는 이를 알지 못하기 때문에 무책임하게 해당 요청을 무시하는 선택을 해도 된다. 그래도 이런건 오류 처리의 모범 사례라 할 수 없다. 적어도 로그는 남겨야 하며
- 비동기 워크플로에서는 재시도(Retry) 전략과 데드 레터 큐(Dead Letter Queue) 전략을 고려할 수 있다.
- 데드 레터 큐로 쓸 수 있는 자원은
AWS::SNS::Topic
또는AWS::SQS::Queue
이다.
- Polling
- 스트림 계열 서비스와 람다 서비스가 통합할 때, 람다는 롱 폴링을 한다. 이 워크플로의 대표적인 이벤트 소스는 SQS, DyanmoDB Streams, Kinesis Data Streams이다. SQS와 상호작용하는 람다 서비스는 큐에서 메시지를 폴(poll)하고, 메시지를 처리하고, 메시지를 정상적으로 처리했음을 알려줄 책임이 있다.
- 마지막의 ‘메시지를 정상적으로 처리했음을 알려주기'를 달성하지 못 하면 해당 메시지는 큐에서 다시 가시적으로 변하고 실패 건으로 인지된다. SQS를 이벤트 소스로 이용할 때는 SQS 자체에 DLQ를 달아주는 전략이 추천된다.
- DyanmoDB Streams, Kinesis Data Streams를 이벤트 소스로 쓸 경우에 AWS는 실패 처리(Failure Handling) 메커니즘을 지원한다. 이것들은 람다의 트리거를 설정할 때 같이 설정한다.
DLQ 적용예
PatientCheckoutFunction
이 람다는 SNS에서 이벤트를 수신한다. 예를들어 이 메시지에 잘못된 형식의 JSON이 담겼을 경우 ObjectMapper에서 오류를 낸다고 하자. 최대 1회의 재시도 수행 뒤 해당 메시지는 DLQ(SNS타입)에 포워딩한다.
PatientCheckoutDLQ:
Type: AWS::SNS::Topic
PatientCheckoutFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: PatientBilling
Handler: org.binchoo.aws.lambda.s3sns.PatientCheckoutLambda::handler
Events:
S3Event:
Type: S3
Properties:
Bucket: !Ref PatientCheckoutBucket
Events: s3:ObjectCreated:*
DeadLetterQueue:
Type: SNS
TargetArn: !Ref PatientCheckoutDLQ
EventInvokeConfig:
MaximumRetryAttempts: 1
Policies:
- S3ReadPolicy:
BucketName: !Sub ${AWS::StackName}-${AWS::AccountId}-${AWS::Region}
- SNSPublishMessagePolicy:
TopicName: !GetAtt PatientCheckoutTopic.TopicName
ErrorHandlingFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: PatientBilling
Handler: org.binchoo.aws.lambda.s3sns.errorhandling.ErrorHandler::handler
Events:
SNSEvent:
Type: SNS
Properties:
Topic: !Ref PatientCheckoutDLQ
ErrorHandlingFunction
이 람다는 PatientCheckoutFunction의 DLQ에서 메시지를 수신하여 잘못된 레코드에 대해 후처리를 진행할 것이다.
ErrorHandlingFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: PatientBilling
Handler: org.binchoo.aws.lambda.s3sns.errorhandling.ErrorHandler::handler
Events:
SNSEvent:
Type: SNS
Properties:
Topic: !Ref PatientCheckoutDLQ
'컴퓨터공학 > 서버리스' 카테고리의 다른 글
[AWS][API Gateway] API Gateway 유형에 따른 ALB Private Integration 차이 /w VPC Link (2) | 2022.09.08 |
---|---|
[AWS][SAM][강의노트] 자바 런타임에서 람다 클래스의 수명 (0) | 2022.03.24 |
[AWS][SAM][강의노트] 다양한 시그니처의 람다 작성해보기 (0) | 2022.03.11 |
[AWS][SAM][강의노트] sam init - 프로젝트 시작하기 (0) | 2022.03.11 |