배경

우리 서비스는 웹과 앱을 모두 운영하고 있는데, 웹 사용성을 고려하여 업로드 한 대용량 이미지가 일부 구형 기기에서 앱 크래시를 일으키는 이슈가 있었다.

요약

CloudFront(CDN)와 Lambda@Edge를 활용하여 클라이언트로부터 받은 파라미터에 따라 S3에 저장된 원본 이미지를 람다(AWS 서버리스 앱)가 리사이즈 하도록 했다.

구조와 흐름

유저가 CDN에 이미지를 원하는 크기와 함깨 요청하면 뷰어 요청에 트리거되는 람다(좌측 상단)가 요청 URL의 크기 정보를 CDN 과 S3에서 사용되는 경로로 변환하여 CDN에 전달한다.

  • 이 경로의 이미지가 있으면 CDN에서 바로 이미지를 응답한다.
  • 이 경로의 이미지가 없으면 CDN은 요청을 S3에 전달하고, S3은 응답한다.
    • 이 때 오리진 응답에 트리거되는 람다(우측 하단)가 실행된다.
      • S3로부터 403 코드를 응답받으면(대부분의 경우) CDN은 요청 URL 로부터 원본 이미지 경로를 파싱하여 S3에 재요청하고 이를 리사이즈한다.
      • 1MB미만이면 유저에게 응답하고, 그렇지 않은 경우 S3에 저장 후 해당 경로로 리다이렉트한다.

(참고) 전반적인 구조

작업순서

  1. CloudFront 생성
  2. CloudFront 의 오리진에 기존 S3 연결
  3. 기존 이미지 요청 시 사용하던 도메인을 S3 에서 CloudFront로 변경
  4. Lambda@Edge 2개 생성
  5. Lambda@Edge의 트리거에 각 CloudFront 뷰어요청, 오리진(S3) 응답 등록
  6. Lambda@Edge 모두 S3에 접근할 수 있도록 람다 IAM role 생성하여 Trust Relationship(신뢰관계) 설정 확인
  7. Lambda@Edge 배포 (serverless 프레임워크 사용)

기타, 회고

Lambda@Edge 와 연결된 CloudWatch와 로그는 연결된 CloudFront가 요청을 받은 리전(Edge)에서만 확인할 수 있다. 이 부분을 놓쳐 코드가 제대로 동작하는지 확인하는 데 헤맸다.

Lambda@Edge는 Lambda 와 비교하여 실행시간(5초), 응답 크기(1MB), 메모리(기본값 128MB) 등 더 많은 제한이 있어 까다로웠다.

아래 링크의 코드와 달리 S3에서 파일이 없는 경우 404가 아닌 403 코드를 응답하여 디버깅하는 데 오래 걸렸다.

 

 

참고

https://aws.amazon.com/blogs/networking-and-content-delivery/resizing-images-with-amazon-cloudfront-lambdaedge-aws-cdn-blog/

+ Recent posts