이미지 리사이징 기능을 구현하기 위해 AWS 에서 S3 와 Lambda 를 이용해서 이미지 리사이징을 거쳐 사용자에게 빠른 로딩 응답을 보장 할 수 있습니다.
AWS 에서 S3 와 Lambda 를 이용해서 image-resizing 을 구현하기 위해 대표적으로 2가지 방법이 존재 합니다.
1. 최초 이미지 등록 시 원하는 크기로 image-resizing 을 해서 S3 에 저장 하는 방법
이 방법은 최초 이미지를 등록 할때 마다 image-resizing  해서 S3 에 저장 하는 방식 입니다.
자세하게 말하자면 특정 S3 의 bucket 에 저장 하면 Lambda 에서 특정 트리거로 인해 image-resizing  작업을 거쳐 원본 이미지 데이터와 함께 resizing 된 이미지도 저장 하는 방식 입니다.
단점 으로는 개발 기간이 많이 필요 하고 기존 S3 에 원본 이미지 파일 저장 함께 resizing 된 이미지 파일도 저장 해야 합니다.
2. S3 + Lambda + CloudFront + API Gateway +Image Handler (서버리스 방식)

두번째 방식은 기존에 저장되어 있던 원본 이미지 파일을 유지 하되 프론트 환경에서 이미지를 불러 올때 마다 먼저 image resizing 전용 Cloud Front 서버로 호출하고 해당 캐시된 리사이징 이미지가 존재 하지 않으면 API gateway 로 호출을 해서 image-resizing  작업(Lambda 함수 호출) 이 발생 하는 Lambda 서버로 트리거 됩니다. 이때 이미지는 리사이징 되면서 리사이징 된 이미지는 S3 에 저장하고 응답 하는 방식 입니다.
- 원하는 해상도 포함해서 이미지를 요청 (Cloud Front 서버에 호출 한다.) ex) https://{아이디값}.cloudfront.net/test2.png?w=200&h=200
- CloudFront 서버에서 캐싱된 이미지가 있으면 바로 응답하지만 만약 존재하지 않으면 API gateway서버에 호출 합니다.
- API gateway서버에서는- S3에 원본 이미지 파일을 가져와서 resizing 작업을 거친 후 최종적으로 사용자에게 응답을 하게 됩니다.
- Lambda서버에서는 요청 받는 이미지를- resizing하게 되고- resizing한 이미지는- S3에 저장을 하게 됩니다. 동시에 사용자에게 응답을 하게 됩니다.
AWS 구축 방법
S3 버킷 생성


S3 콘솔 에서 bucket 을 생성 하도록 합니다.
생성한 bucket 에 이동하고 권한 → 버킷 정책 으로 이동 해서 버킷 정책을 변경 합니다.
| 1 | { | 
IAM 생성

AWS IAM 콘솔 접속 해서 왼쪽 메뉴에  정책 우측 상단에 정책 생성 을 클릭 합니다.

JSON 탭 선택 후 다음과 같이 입력 합니다.
| 1 | { | 

이번에는 역할을 생성 해야 합니다. AWS IAM 콘솔 접속 해서 왼쪽 메뉴에  역할 우측 상단에 역할 생성 을 클릭 합니다.

신뢰할 수 있는 엔티티 유형 에서 AWS 서비스 를 선택하고 사용 사례 를 Lambda 로 선택 하도록 합니다.

이전에 생성했던 정책 명을 검색해서 선택 후 다음을 눌러서 역할을 생성 합니다.
| 1 | const AWS = require('aws-sdk'); | 
index.js 파일에 해당 로직을 추가 하도록 합니다. 간단하게 말하자면 sharp 라이브러리를 이용해서 S3 에 저장 된 원본 이미지를 가져와서 Resizing 처리 하고 이후 S3 에 Resizing 된 이미지 저장과 동시에 응답 하는 로직 입니다.
Lambda 생성

Lambda 콘솔에 접속 해서 함수 생성 버튼을 클릭 합니다.

코드 소스를 업로드를 해야 합니다. 이미지 resizing 을 하기 위해서는 Node.js에서 제공하는 Sharp 라이브러리를 사용 할 예정입니다. 고성능 이미지 처리를 위해 널리 사용되는 라이브러리 이고 이미지 크기 조정, 자르기, 회전, 형식 변환 등 여러가지 기능을 제공 합니다.
우선 Amazon Linux OS 환경에서 Node 를 설치를 하고 npm install sharp aws-sdk  명령어로 라이브러리를 설치 하도록 합니다. 그럼
- node_modules
- package.json
- package-lock.json
파일이 생성 되는데 모두 zip 파일로 압축 해서 업로드를 하도록 합니다.

아래 메뉴 탭에서 구성 버튼 클릭 후 왼쪽 메뉴 일반 구성 버튼을 클릭 합니다. 여기서 우측에 편집 버튼을 클릭 합니다.

원활한 이미지 resizing 하기 위해서는 적어도 메모리 512 MB 필요 합니다. 그리고 제한 시간을 15초로 설정 합니다.  이전에  역할 에서 생성한 IAM 역할을 선택 후 저장 버튼을 클릭 합니다.
API Gateway 생성

AWS API gatway 콘솔에 이동해서 API 생성 하도록 합니다. 여기서 HTTP API  를 선택 및 구축 하도록 합니다.

API 이름을 지정하고 모두 default 로 최종 생성 합니다.

생성한 API 접근 후 Routers 버튼 클릭 경로 생성 버튼을 클릭 합니다.

모든 경로에 대해 이미지 요청을 받을 수 있도록 설정 할 수 있도록 /{proxy+} 입력 후 생성 버튼을 클릭 하도록 합니다.

그 다음은 왼쪽 메뉴에서 Integrations 클릭 후 상단 탭 통합을 경로에 연결→ 통합을 경로 및 관리 버튼을 클릭 합니다.

통합 유형 을 Lambda 함수로 선택 후 통합 대상 을 선택 해야 하는데 이미 생성한 Lambda 로 지정 후 생성 버튼을 클릭 하도록 합니다.

정상적으로 Lambda 로 통합 설정 완료 되었습니다.

그 다음은 왼쪽 메뉴에서 Stages 클릭 후 상단 탭 생성버튼을 클릭 합니다.

이름을 prod 지정 후 생성 버튼을 클릭 합니다.

스테이지를 생성한 prod 로 선택 후 배포 버튼을 클릭 합니다.

배포 버튼을 클릭 합니다.
Cloud Front 생성

AWS Cloud Front 콘솔에 이동해서 배포 생성 버튼을 클릭 하도록 합니다.

Distribution name 지정 하고 Next 버튼을 클릭 합니다.

Origin 설정 해야 합니다. API Gateway 를 선택 하도록 합니다. 그런 다음 Browse APIs 버튼을 클릭 합니다.

적절한 Region 을 선택 하고 APIGATEWAY Version 을 HTTP API 로 선택 후 이전에 생성 했던 API Gateway 를 선택 하도록 합니다.

Origin path - optional 입력 박스에서 /prod 로 입력 후 Next 버튼을 클립 합니다.

생성한 Cloud Front 선택 후 상단 탭에 동작 버튼을 클릭 후 동작 생성 버튼을 클릭 하도록 합니다.

경로 패턴 을 * 로 입력하고 원본 및 원본 그룹 을 이전에 생성한 API Gateway 로 선택 합니다.

캐시 정책에서 Create cache policy 클릭 하도록 합니다.

적절한 cache policy의 이름 지정하고 Cache TTL 을 1년 으로 지정 합시다.  그리고 쿼리 문자열 을 모두 로 선택 후 저장 합니다.

캐시 정책 을 방금 생성 한 캐시 정책으로 선택 하고  원본 요청 정책 을 Create origin request policy 버튼을 클릭 합시다.

적절한 origin request policy 이름을 지정하고 쿼리 문자열 을 모두 로 선택 후 생성 버튼을 클릭 하도록 합니다.

생선한 원본 요청 정책 을 선택 하고 마지막으로 Create behavior 버튼을 클릭 합니다.
실험 해보기


우선 크롬 브라우저 통해 https://${아이디값}.cloudfront.net/test9.jpg?w=200&h=200 접근 하면  CloudFront -> API Gateway (HTTP API) -> Lambda (리사이징 처리) 이렇게 처리가 됩니다.
x-cache 값이 Miss from cloudfront 라고 나오는데 CloudFront 에서 캐시 없다는 의미 입니다. 속도는 1.09s 발생 하였습니다.


다른 브라우저 통해 https://${아이디값}.cloudfront.net/test9.jpg?w=200&h=200 접근 하면 CloudFront(캐싱됨) 캐싱된 이미지가 있어서 빠르게 응답 할 수 있었습니다.
x-cache 값이 Hit from cloudfront 라고 나오는데 CloudFront 에서 캐시 있다는 의미 입니다. 속도는 70ms 로 이전 보다 빠르게 이미지 데이터를 가져 올 수 있었습니다.
Copyright 201- syh8088. 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.
 
            