서버리스를 경험해보고 싶은데 운영을 경험하고자 아주 가볍게 MVP만 구성했었던 서비스가 눈에 띄었다. 기능을 다 구현해도 API가 10개 남짓이라 마이그레이션하기 비교적 쉽고 OAuth 활용 인가, 파일 전달 등 서버리스에서 고민해볼 사항들이 있어서 해당 프로젝트를 서버리스로 마이그레이션해보기위해 아키텍처를 고민하기 시작했다.
가장 익숙한 CSP가 AWS여서 서버리스 구현은 AWS로 진행하고 있다.
Azure 가상머신을 활용한 기존 아키텍처는 위와 같다.
Auzre를 선택한 이유는 AWS 프리티어가 끝나서 Azure 학생 구독으로 무료 서버를 사용하기 위해서이며 이미지 파일 사용에서 변동이 없기 때문에 별도의 스토리지를 사용하지 않고 public 폴더를 사용했다. 로그도 Node.js의 winston 라이브러리로 직접 남겼다.
위에서는 개발 과정에서 간단한 CI/CD로 Github과 Github Actions를 활용한 부분도 포함했지만 서버리스 아키텍처에서는 CI/CD 부분은 다루지 않을 예정이다.
사용자 뒷편에서 AWS의 CodeCommit, CodeBuild 등을 활용하거나 Jenkins 서버를 따로 두거나 Docker, Kubernetes로 구동/배포/관리하거나 다양한 방법을 목적과 필요에 맞게 활용할 수 있다.
백엔드 비즈니스 로직 ➡️ AWS Lambda (+ CloudWatch Logs - Default)
이미지 파일 저장 및 제공 ➡️ AWS S3
위의 두 서비스를 중심으로 살을 붙이면서 아키텍처를 비교해보려 한다.
S3를 활용하는 방법부터 비교해보자.
S3는 서버리스 스토리지 서비스로 대부분의 서버리스 아키텍처에서 파일을 통한 배포 관리와 상태 저장, 기타 정적 파일 저장 및 배포 등의 다양한 용도로 활용한다.
S3로 정적 파일을 배포하는 경우라면 S3 앞에 CloudFront를 붙이는 구조가 보편적이다. 필요하다면 DNS를 위해 Route 53까지 붙일 수 있다.
S3를 퍼블릭으로 공개한다면 호출한만큼 과금이 되어 비정상적인 접근을 막을 필요가 있고 이를 위해 CloudFront를 붙인다.
S3 앞에 CloudFront를 붙이면 다음과 같은 이점이 있다.
[Amazon Web Services 한국 블로그] 실전 Amazon S3와 CloudFront로 정적 파일 배포하기
단순 정적 파일 배포가 목적이라면 CloudFront 활용을 고려하겠지만 API에서 활용한다면 API Gateway에서 접근하거나 API Gateway를 통해 Lambda를 호출해서 비즈니스 로직에 활용하는 방법도 가능하다.
🚧 하지만 중간에 Lambda를 활용하는 방법은 꼭 필요하지 않다면 권장하지 않는다. 단순 업로드/다운로드라면 비효율적이고 업로드/다운로드 대상이 손상될 가능성이 있다.
그래서 위와 같이 API Gateway에서 IAM 사용자를 통해 S3에 접근해서 업로드/다운로드를 진행하는 것을 권장한다.
API Gateway API를 통해 Amazon S3에서 이진 파일에 액세스
자습서: API Gateway에서 Lambda 사용
AWS가 일반적으로 제시하는 구조로 API Gateway ➡️ Lambda ➡️ DynamoDB 로 이어지는 로직이다.
Lambda가 실제 백엔드 비즈니스 로직을 수행하고 API Gateway에서는 앞에서 다음의 기능을 제공한다.
위의 두 사례를 합쳐 프로젝트에 적용할 아키텍처를 구성하면 다음과 같다.
프로젝트에서 기존에 사용하던 MongoDB를 그대로 사용하고 S3에서 이미지를 가져온다.
S3를 따로 배치해둔 이유는 0️⃣을 참고하여 다양하게 적용이 가능하기 때문이다. 프로젝트에서는 API Gateway를 통해 접근할 예정이다.
2022년 4월부터 API Gateway없이 Lambda를 HTTPS 엔드포인트로 사용할 수 있게 되어 API Gateway가 없이 백엔드 리소스로 활용할 수 있게 되었다.
AWS Lambda 함수 URL을 이용하여 편리하고 안전한 API 서버와 클라이언트 만들기
장점
Lambda 함수를 엔드포인트로 직접 실행하여 간단하고 편리하게 API를 제공하고 API Gateway 미사용으로 시간, 비용을 절약할 수 있다.
단점
API Gateway에서 제공하던 IAM, Cognito와 Authorizer를 통한 보안 보완과 대량 호출 관리가 어렵고 Function URL에서 제공하는 엔드포인트를 그대로 활용해야하므로 커스텀 URL을 활용할 수 없다.
🚨 Webhook 핸들러와 같이 Lambda로 간단히 구현하여 쓸 수 있는 경우에 유용하고 백엔드 아키텍처로의 활용은 권장하지 않는다.
하지만 그럼에도 프로젝트에 적용한다면 아래와 같이 활용할 수 있다.
2️⃣와 동일하게 일반적으로 백엔드 아키텍처로 제안하지는 않지만 앞서 등장했던 2️⃣의 장점을 강화하고 단점을 보완한 아키텍처로 이해하기 쉽고 다양한 사용 사례로 확장할 수 있는 조합이다.
API Gateway를 완벽히 대체할 수는 없지만 OAC를 지원하여 람다 원본을 보호하고 장점인 속도를 가속화한다는 점에서 CloudFront를 붙일 수도 있다.
AWS Lambda 오리진 및 Amazon CloudFront를 활용한 웹 애플리케이션 가속
여기서 Lambda와 CloudFront가 연결된다면 Lambda@Edge 활용이 가능하다.
Amazon CloudFront의 기능 중 하나로서 CDN을 통해 성능을 개선하고 지연시간을 단축한다. CloudFront 트리거를 사용한 Lambda 함수 간접 호출이라고 설명할 수 있다.
CloudFront가 Lambda를 호출하는 방식은 다음과 같다.
기존 아키텍처에서 아래처럼 Lambda를 Lambda@Edge로 간접 호출해서 성능을 향상시켰다고 이해할 수 있다. Lambda@Edge는 CloudFront의 기능으로 아키텍처는 처음에 제시한 이미지와 같다.
CloudFront Lambda AWS Lambda @Edge 와 함께 사용
이번 글은 아키텍처 비교가 목적이니 간단하게만 정리하겠다.
완전관리형 서비스 서버리스. 눈에 보이는 서버가 없고 따라서 내가 서버를 관리할 필요가 없다. 서버를 관리해야하면
등의 단점이 발생할 수 있는데 이 모든 걸 해결한다.
사용한만큼 부과하고 유동적인 트래픽을 커버할 수 있으며 결국 리소스를 효율적으로 사용하고 절약할 수 있다.
벤더 종속적이다. 말 그대로 서버 관리를 CSP에 위임하기 때문에 마이그레이션이 굉장히 어렵고 따라서 다른 CSP로 옮기기가 쉽지 않다.
이런 점 때문에 하나의 CSP에 서버리스로 정착한다면 다른 서비스를 활용할 때도 연결성이 가장 좋은 해당 CSP의 서비스를 활용하게 된다.
Lambda 비용은 서울 기준 아래와 같으며
예제로 제시한 모바일 애플리케이션 백엔드에서 계산한 요금은 다음과 같다.
단순하게 설명하기 위해 애플리케이션은 매월 3백만 건의 요청을 처리한다고 가정합니다. 평균 함수 실행 기간은 120밀리초입니다. x86 기반 프로세서에서 1,536MB의 메모리로 함수를 구성합니다. 요금은 다음과 같이 계산됩니다.
~~ 생략 ~~
총 월별 요금
총 요금 = 컴퓨팅 요금 + 요청 요금 = 2.33 USD + 0.40 USD = 월별 2.73 USD
서버를 전부 관리해주는 것에 비해 생각보다 저렴해보일 수 있다.
개인적인 서버리스의 단점인 종속성을 CSP에서는 고객 확보를 위해 잘 활용해야하기 때문에 서버리스에 대해서는 비용을 높게 책정하지 않는 것이 아닐까 추측한다.
이제 고민은.. 마이그레이션이니까 위 아키텍처를 직접 구현해야한다. 하하...
아키텍처별 장단점은 직접 구현하면서 체감해보고 트러블슈팅하면서 학습하겠다. 아자아자
틀린 부분이 있으면 많은 지적 부탁드립니다..🥹