Serverless
- 개발자가 서버를 관리 / 프로비저닝 할 필요가 없는 새로운 패러다임
- 단지 코드(함수)를 배포
- 서버가 없다는 뜻이 아님!
- 서버를 관리 / 프로비저닝 할 필요가 없고, 보이지 않음
- AWS 서버리스
- Lambda, DynamoDB, Cognito, API Gateway, S3, SNS & SQS, KDF, Aurora Serverless, Step Functions, Fargate
AWS Lambda
- 가상의 함수 (Virtual Function) - 관리할 서버 없이, 단지 코드를 프로비저닝하고 함수를 실행
- 시간 제한 - 짧은 실행시간 (최대 15분)
- 온디맨드로 실행 (함수가 실행될 때만 비용 발생)
- 스케일링 자동화
- 장점
- 가격 책정 쉬워짐 - 수신 요청 수에 따라 청구 / 프리티어에서도 컴퓨팅 시간 40만 GB, 100만 람다 요청 제공
- 다양한 AWS 서비스와 통합됨
- 많은 프로그래밍 언어와 통합됨
- CloudWatch 모니터링 통합됨
- 함수 당 10GB 램 프로비저닝 가능
- 램 증가 시 CPU와 네트워크 성능도 함께 향상됨
- 람다 컨테이너를 실행해야 할 경우 > 람다 런타임 API를 구현하지 않는 경우 ECS or Fargate에서 컨테이너를 실행해야함
Lambda - 이벤트 처리방법 1. 동기식 호출 (Synchronous Invocations)
- 동기식 : 결과를 기다리는 형태의 직접호출 / 오류 발생 시 클라이언트에서 핸들링 (retry, 지수 백오프 등)
- 동기식 동작 1 - 유저 호출
- ELB(ALB), API Gateway, CloudFront (Lambda@Edge), S3 Batch
- 동기식 동작 2 - 서비스 호출
- Cognito, Step Functions
Lambda- ALB와 통합
- ALB에서 람다를 호출하기 위해서는 ALB 타겟 그룹에 Lambda 등록 필요
- 요청 : HTTP/HTTPS 요청 -> ALB에서 json 포맷으로 요청 변환(쿼리스트링, 헤더, 바디) -> Lambda에서 처리
- 응답 : Lambda에서 json 포맷으로 응답 -> ALB에서 HTTP/HTTPS 응답으로 변환
- ALB Multi-Header values
- ALB 설정을 통해 다음과 같은 multi value를 json에서 배열 형태로 변환하여 람다에게 요청 가능
- ?name=foo&name=bar
- "queryStringParameters": {"name": ["foo","bar"]}
Lambda - 이벤트 처리방법 2. 비동기식 호출 (Asynchronous Invocations)
- 이벤트가 내부의 이벤트 대기열에 위치
- 람다 함수는 이벤트 대기열을 읽어 처리
- 문제가 생길 경우 람다 함수 측에서 재시도
- 3번 재시도. 처음 재시도는 즉시 / 두번째는 1분 뒤 / 세번째는 2분뒤
- 람다 측에서 재시도를 하므로 람다 함수는 멱등성이 보장되어야함
- 재시도 시 CloudWatch 로그에서 로그 엔트리가 복제됨
- 재시도 실패 이벤트를 SQS, SNS로 보내 재시도 끝난 뒤 DLQ 정의 가능
- 작업 속도를 높여야 하는 상황에서 결과를 기다릴 필요가 없는 경우 사용
- 비동기식 동작 서비스
- S3, SNS, CloudWatch Events, EventBridge, CodeCommit, CodePipeline
Lambda - 이벤트 처리방법 3. 이벤트 소스 맵핑 (Event Source Mapping)
- 람다가 서비스에서 요청을 폴링하는 방식
- 해당 경우 람다 함수는 동기적으로 호출
- KDS, SQS & SQS FIFO Queue, DynamoDB Streams
- Stream 방식 (Kinesis, DynamoDB)
- 스트림에 대한 iterator 생성
- 샤드 레벨에서 순차적으로 아이템 처리
- 읽기 시작 위치 지정 가능 (새로운 아이템만 읽기, 샤드 시작위치, 타임스탬프 기준 읽기 구성)
- 읽는 데이터는 제거되지 않음 (다른 소비자가 Kinesis, DynamoDB 내 데이터를 읽을 수 있음)
- 사용사례 : 낮은 트래픽 or 높은 트래픽
- 낮은 트래픽 : 배치 윈도우를 통해 레코드를 축적
- 높은 트래픽 : 람다가 샤드 레벨에서 동시에 여러 배치를 처리하도록 병렬적으로 설정 가능 (사드당 최대 10개 배치 가능)
- 오류 발생 시 함수가 성공할 때 or 배치 아이템 만료 전까지 배치가 다시 처리
- 배치에 오류 발생 시 처리가 중단될 수 있음
- 순차 처리를 위해 오류 해결 전까지 해당 오류의 영항을 받는 배치의 처리는 중단됨
- 오래된 이벤트 제거 / 재시도 횟수 제한 / 오류 시 배치 분할 설정 가능 (람다 타임아웃 발생 시 유용)
- 대기열 방식 (SQS & SQS FIFO)
- 이벤트 소스 매핑이 긴 폴링을 이용해 SQS 폴링
- 배치 사이즈는 1 ~ 10 message까지 설정 가능
- queue visibility timeout을 람다 함수 timeout의 6배로 설정 권장
- DLQ 사용 시 SQS에서 설정 (람다 DLQ는 비동기식 호출에만 동작하므로)
- 또는 실패 시 이벤트를 목적지에 전송 가능
- FIFO 큐 사용 시 람다는 순차적 처리 지원
- 처리를 위한 람다 수는 큐의 활성 메시지 그룹 수와 동일 (그룹ID)
- 람다에서 데이터 처리 시 큐 대기열에서 삭제됨
Lambda - Event, Context 객체
- 이벤트 객체
- Json 형태의 함수가 처리할 데이터를 갖고있는 문서
- EventBridge, SQS 등은 람다함수가 이벤트를 처리할 때 필요한 모든 정보를 가짐
- 사용하는 런타임에 따라 다른 객체로 변환됨 (ex. dict type in python)
- 입력되는 인자, 서비스 인자, 이벤트의 소스, 이벤트 리전 포함
- 컨텍스트 객체
- 런타임 환경과 호출 자체의 데이터를 제공
- AWS 요청 ID, 함수명, 사용가능한 메모리량 등 포함
- 람다 함수 안에서 사용 가능
Lambda - Edge Functions
- 많은 현대 애플리케이션은 애플리케이션 자체에 요청 도달 전에 엣지에서 로직을 실행
- 엣지 함수 : CloudFront 배포 시 연결됨
- 지연시간을 최소화 하려는 경우, 사용자와 가까운 곳에서 함수를 실행
- CloudFront는 두가지 타입을 제공 - CloudFront 함수, Lambda@Edge
- 서버 관리 필요 X, 전역적으로 배포
- ex) CDN 콘텐츠를 커스터마이징
- 사용량에 따라서만 비용 지불, 완전한 서버리스
- 사용사례
- 웹사이트 보안 및 개인정보 보호
- 엣지에서의 동적 웹 애플리케이션
- 검색 엔진 최적화 (SEO)
- Origin과 데이터센터 간 지능형 라우팅 수행
- 엣지에서의 봇 완화
- 엣지에서의 실시간 이미지 변환
- A/B 테스트
- 사용자 인증 / 권한부여 / 우선순위 지정 / 추적 및 분석
- Edge Functions 동작 과정
- 클라이언트가 CloudFront에 요청 전송 (Viewer Request)
- CloudFront에서 오리진 서버로 요청 전송 (Origin Request)
- 오리진 서버에서 CloudFront로 응답 (Origin Response)
- CloudFront에서 클라이언트로 응답 (Viewer Response)
- CloudFront 함수
- JS로 작성한 가벼운 함수
- 대기시간이 중요한 큰 규모의 CDN 커스터마이징 시 사용
- 시작 시간이 밀리초 미만 / 초당 요청을 수백만 수행 가능
- 뷰어 요청 / 응답을 바꾸는 데만 사용
- CloudFront의 네이티브 기능, 모든 코드가 CloudFront에서 직접 관리됨
- 캐시 키 정규화 (요청 속성을 변환해 최적의 캐시 키 생성)
- 헤더 조작 (요청, 응답에서 헤더 삽입, 수정 삭제)
- URL 재작성, 리디렉션
- 인증 요청 (요청 허용, 거부 가능한 JWT 토큰 검증)
- Lambda@Edge
- 뷰어, 오리진 요청 / 응답 바꿀 수 있음
- Node.js or 파이썬으로 작성되는 함수
- 요청 수는 초당 수천 회
- 함수를 특정 리전에 작성하면, CloudFront는 해당 함수를 모든 위치에 복제
- 시작 시간이 5 ~ 10초 (함수에서 로직을 많이 수행 가능)
- CPU와 메모리 조정 가능
- 코드에서 써드 라이브러리 의존 가능 (ex. AWS SDK를 통해 다른 AWS Service 이용)
- 외부 서비스에 네트워크 액세스를 통한 처리 가능 (큰 규모의 통합 제공)
- 파일 시스템 엑세스, HTTP 요청 본문 엑세스 획득 가능
Lambda - VPC
- 기본적으로 람다는 VPC 외부에서 실행
- 따라서, 기본적으로 람다는 VPC 내 리소스에는 액세스 불가능
- VPC에 람다 배포 가능
- VPC ID 및 서브넷 정의, 람다 함수에 보안그룹 배정
- 람다의 ENI (Elastic Network Interface) 서브넷에 생성
- 이를 위해 람다는 AWSLambdaVPCAccessExecutionRole 필요
- 람다함수 -> ENI -> VPC 내 AWS service 접근
- 이를 위해 AWS Service의 보안그룹이 람다 보안그룹에 대한 액세스 허용 필요
- 기본적으로 VPC 내 람다 함수는 인터넷 액세스 권한이 없음
- 람다 함수를 공용 서브넷에 배포해도 인터넷 액세스 or 퍼블릭 IP 접근권한을 얻을 수 없음
- VPC 내 람다 함수를 배포하고 인터넷 액세스를 하기 위해서는 NAT 게이트웨이 or NAT 인스턴스를 이용
- VPC 내 람다 함수 -> 공용 서브넷의 NAT -> VPC의 IGW -> 인터넷 액세스
- VPC EndPoint를 사용하면 NAT 없이도 VPC 내 람다 함수가 프라이빗 액세스로 AWS 서비스에 이용 가능
- VPC 내 람다 함수를 배포해도 NAT, VPC 엔드포인트 없이도 CloudWatch Logs는 정상 작동
Reference