개요
AWS Lambda를 이용해 Python 기반의 Serverless 서비스를 개발 및 운영할 때, 주로 쓰이는 것으로 보이는 여러 방법(조합)이 있는데,
주로 많이 사용되는 방법은 다음과 같습니다.
- FastAPI + Magnum
- Chalice
- Flask + zappa
해당 글에서는 FastAPI + Magnum에 서비스 구조에 대해 이해한 바를 작성하며, 다음 내용을 주로 작성해 보려고 합니다.
- FastAPI + Magnum 해당 방법의 특징
- Magnum에 대한 이해
- 구현 방법에 대한 개괄적인 설명
Serverless FaaS 서비스인 AWS Lambda 에 대한 이해는 이전글을 참고
- https://yubi5050.tistory.com/255 : Serverless 서비스 - AWS Lambda
Fastapi + mangum 사전 조사 정보
FastAPI가 등장한 이후로, FastAPI를 Serverless로 구현해 보려는 시도가 생기면서, 국내 블로그 글이나 스택오버플로우에도 정보가 종종 보이는 것 같으며, 단순 구현에 대한 시도를 넘어, production에 적용해보 더라도 괜찮을 것 같다는 생각을 가졌습니다.
관련 사례 블로그/링크
- [FastAPI] 15. FastAPI를 Serverless로 배포 하는 방법 - Magnum
- [FastAPI] Mangum + Lambda + SAM 을 사용해 간단하게 배포하기 글 링크
- [스택오버플로우] Magnum은 매우 Light 하고, Production에서도 아직까진 잘 동작하고 있다
Mangum 이란?
여기서 mangum이 등장하는데, 공식문서에서는 한줄로는 다음과 같이 설명합니다.
ASGI Application와 AWS 서비스(Lambda / API Gateway / ALB / Lambda Edge Events) 간의 어댑터 역할 수행
주요 기능
- API Gateway HTTP or REST API / ALB / Function URLs / Cloud Front 등의 서비스에 대한 이벤트 핸들러 역할
- Starlette, FastAPI, Quart, Django 프레임워크 들과의 호환성
- payload 압축이나, 이진 미디어에 대한 압축 가능 (GZip, Brotli 활용)
만약 mangum을 가볍게 이해하고 넘어 가고 싶다면,
일반적으로 Python Framework를 배포할 때 Gunicorn, Uvicorn 등 을 사용해서 WAS에 배포하는 것처럼
Lambda 서비스에서도, WAS(Web Application Server)를 구성하는데 있어, mangum을 같이 사용한다.
정도로 생각 하고 넘어 갈 수 있을 것 같습니다.
Mangum 이 FastAPI에 필요한 이유
사실 그렇구나.. 하고 넘어가려다가 다음과 같은 의문이 들었고,
gunicorn은 프로세스 들을 prefork 하여, 대기 큐에 넣는 매니징하는 역할을 하기에 존재하는데,
lambda에서는 요청별로 독립적인 인스턴스 환경에서 실행되기에, 한 인스턴스(코드뭉치)에 mangum 까지 필요한가?
ref ) labmda의 요청에 대한 실행 과정 설명 (with. 인스턴스 생성)
따라서 mangum이 존재 의의에 대해 좀더 찾아보게 되었고, 해답은 다음 github issue 토론 내용 에서 발견 할 수 있었습니다.
토론 내용이 길어서, 내용을 정리하면 다음과 같습니다.
- 질문 : FastAPI 배포시 적절한 ASGI 서버는 무엇인가요? (+일반 배포 or 서버리스 경우)
- 답변 : tjango (FastAPI 만든 사람)의 FastAPI 설계 원리에 대한 설명글
토론 내용 정리
- Uvicorn, Hypercorn 및 Daphne은 모두 ASGI 약관에 따른 서버 애플리케이션으로 HTTP를 처리하고, ASGI 프레임워크로 구축된 애플리케이션에 매개변수를 전달함
- FastAPI는 ASGI 프레임워크로 HTTP와 직접적으로 통신하지 않고, 사용되는 app 객체가 앞선 서버에서 전달받은 매개변수를 바탕으로 실행됨
- 따라서 HTTP를 통해 들어온 인자들을 FastAPI 앱에 전달하려면 무언가가 필요하다! (ex. FastAPI app 실행시 uvicorn app.py 하는 이유)
- 일반적인 배포에서는 Uvicorn, Hypercorn, Daphne을 활용하여 처리할 수 있지만, Lambda 환경에서는 CloudFront / API Gateway 등을 통해 들어온 HTTP 인수 들에 대해 추가적인 처리가 필요하고, 이를 구현 해놓은 것이 Mangum 이다.
- 따라서 Lambda 환경에서는 Mangum 만 사용한다.
구현 방법
구현 방법의 상세한 설명은 앞서 소개해드린 블로그들에 상세히 나와 있기에, 개괄적으로만 설명합니다.
1. 새로운 프로젝트 폴더, 가상환경에 package 설치
- pip install fastapi, mangum, boto3(필요시), 필요 패키지
2. aws 환경 준비
- iam 생성 및 권한 부여 / s3 bucket 생성 등 / 로컬에 aws 관련 config key 등록
3. 서버리스 코드 작성 (.py)
- fastapi 기반의 코드 작성 (저는 signed 된 s3 업로드 path를 가져오는 기능이 필요해서 다음과 같이 작성하였습니다)
from fastapi import FastAPI, APIRouter
from mangum import Mangum
from pydantic import BaseModel
import boto3
app = FastAPI()
MY_ACCESS_KEY = '<your aws access key>'
MY_SECRET_KEY = '<your aws secret key>'
BUCKET = '<your aws s3 bucket name>'
s3_client = boto3.client('s3', region_name='ap-northeast-2',
aws_access_key_id=MY_ACCESS_KEY, aws_secret_access_key=MY_SECRET_KEY
)
expiration=3600
class FileInfo(BaseModel):
file_name:str
@app.get("/")
async def health_check():
return {"message": "OK"}
@app.post(
path="/get-upload-url", summary="get upload url"
)
async def get_upload_url(payload:FileInfo):
object_name = payload.file_name
response = s3_client.generate_presigned_post(BUCKET, object_name, ExpiresIn=expiration)
return response
handler = Mangum(app)
4. Library zip 파일 만들기
- 구동에 필요한 패키지 라이브러리 들을 layer로 업로드 하기 위함
- labmda는 최종적으로 <패키지 layer> - <코드 layer> 로 구성됩니다.
$ mkdir python && cp -rf venv3/lib/python3.11/site-packages/* ./python
$ zip -r serverless-fastapi.zip python/
5. Lambda 만들기 (코드 파일 .py / .zip 업로드)
- 해당 코드 파일은 .py 내용만 복사하거나, 용량이 많다면 압축된 파일로 업로드
6. Layer 만들기 lambda 연결하기
- 앞서 압축한 Library zip을 layer로 등록하고 lambda와 연결해 줍니다.
7. api-gateway 만들기 (api 연결하기)
- aws의 api-gateway 서비스를 이용해 api를 구성하며 자원과 메소드를 생성해주고 lambda 함수와 연결해 줍니다.
- 메소드 생성시 프록시와 통합이란 체크 버튼 (체크)
8. Api 배포하기 (API 요청을 통해 테스트)
- 제가 사용한 body는 다음과 같습니다.
- body : { "file_name":"image.png" }
9. Lambda 함수 로그 확인
- Lambda 에서 모니터링 탭을 누르면 자동으로 Cloudwatch에서 로그가 확인 가능합니다.
'AWS > Serverless Lambda' 카테고리의 다른 글
[AWS Lambda] Python Serverless 서비스 (Chalice) (0) | 2023.06.06 |
---|---|
[AWS] Serverless 서비스 - AWS Lambda (0) | 2023.06.06 |