본문으로 건너뛰기

serverless-image-handler

· 약 6분

Serverless Image Handler는 AWS에서 제공하는 다양하고 검증된 서비스들을 조합하여 만들어진 솔루션(?)입니다.

운영하는 서비스에 종속적인 기능들이 아니라면 한번 찾아보면 이미 만들어져 있을 법한 것들이 있기 때문에 한번 서칭해보면 좋을 듯 한데요. 그 예로, 로깅 중앙화, 제가 사용해본 서버리스 이미지 핸들러 등등이 존재합니다.

https://github.com/aws-solutions/

아키텍처

Overview < 출처: https://github.com/aws-solutions/serverless-image-handler >

해당 기능은 말그대로 서버리스 환경에서 이미지를 요청시에 즉시 핸들링해주는 솔루션입니다. 제가 맡고 있는 서비스는 원본 이미지를 다양한 크기로 이미지를 노출시킬 수 있어야 했는데요. 미리 만드는 방법도 있지만 이는 정적이고, 마이그레이션이 다소 불편하며, 관리하는 측면에서 만족스럽지 못 했습니다.

이것 이외에도 CloudFront + Lambda@Edge를 사용하는 방법도 있으니 참고하시기 바랍니다.

기능

  1. 이미지를 다양한 형태로 핸들링할 수 있습니다.
    • 해당 기능은 런타임 환경이 Nodejs에서 이루어지며, Nodejs에서 이미지 처리하는 라이브러리인 sharp를 사용하고 있습니다.
    • 리사이징
    • 포맷 변경
    • 퀄리티 변경
    • ...
  2. 이미지 URL 변조
    • 만약 우리가 300x300 사이즈의 이미지를 제공하고 이를 어느 누구나 변경해서 요청할 수 있다면 어뷰징 대상이 될 수 있을 것 입니다.
    • 300x301, 300x302, 300x303, 300x... 😱
    • signature 라는 파라미터를 받아서 이를 변조하지 못하도록 제공하고 있습니다. (해당 기능은 secret-manager를 통해 별도의 키를 만들어서 사용합니다.)
  3. 이미지 자르기, Amazone Rekognition을 활용한 분석 등등을 제공합니다.
  4. ...

사용방법

Default 방식

const imageRequest = JSON.stringify({
bucket: "<myImageBucket>",
key: "<myObjectKey>",
edits: {
resize: {
width: ...,
height: ...
}
}
});
const url = `${CloudFrontUrl}/${btoa(imageRequest)}`;

<img src=`${url}` />

위 방식은 url을 json문자열을 base64으로 인코딩해서 전달하는 방식으로 json 안에는 bucket, object key, sharp 정보(?) 등을 포함되어 있습니다. sharp 관련된 내용은 관련 문서를 참고해서 적용하면 손쉽게 적용할 수 있습니다.

Thumbor 방식

const url = `${CloudFrontUrl}/filter:format(webp)/${object_key}`;

<img src=`${url}` />

위 방식은 기존 url과 비슷하게 유지하면서 사용할 수 있는 방법 중에 하나로, path 중간에 filters:~~~를 넣어 옵션을 적용할 수 있습니다.

사용 후기

장점

  1. CloudFormation으로 제공되기 때문에 손쉽게 구축할 수 있습니다.

    • AWS 솔루션의 공통적인 장점이겠지만, cdk를 활용해 CloudFormation으로 빌드하여 제공하고 있습니다.
  2. CloudFront를 사용하기 때문에 한번 요청되면 캐시되어 비용 절감이 가능하다.

    • CloudFront라는 CDN 서비스를 사용하고 있기 떄문에(사실 누가 CloudFront없이 S3를 바로 붙이겠냐만은...) 응답이 캐싱되어 첫 요청이외에는 비용이 많이 절감됩니다.
  3. On the fly 방식이기 때문에 관리가 용이합니다.

단점

  1. 람다 자체가 요청/응답에 대한 페이로드가 6MB 제한이 있기 때문에 큰 이미지를 전달할 수 없습니다.

    • base64로 인코딩해서 전달하기 때문에 6MB보다 더 작아야 합니다. 😥
  2. 다소 과할 수 있다.

    • 어느 것이나 그렇지만 단순하게 쓰고자한다면 조금 과할 수 있다.
  3. 6.0.0 버전까진 gif 대응이 안된다.

    • sharp0.30.0 버전부터 gif를 지원하기 시작했지만, 0.27.0 버전을 사용하고 있기 때문에 대응이 안된다.
    • gif를 지원하려면 결국엔 별도 빌드를 거쳐서 사용해야함

결국, 1,3번 단점 때문에 나의 서비스는 api gateway에 별도 path를 추가 및 직접 S3 서비스를 연결해서 사용하고 있습니다.