[1/2] AWS Cloudfront로 S3 origin에 대한 CDN 프록시 서버만들기 (이미지 최적화)
사용 동기
할로윈 이벤트 같이 트래픽이 몰릴 때 메인 피드 이미지 로딩이 느려지는 현상이 발생했다.
정적 이미지 서버로서 AWS S3 버킷을 사용했었는데, 모든 트래픽이 하나의 S3 origin 서버로 몰리면서 병목이 생긴 것이다. 그래서 이미지 서버 다중화를 생각하게 되었고 AWS에서 제공하는 CloudFront로 CDN을 붙이기로 했다.
CDN 란?
content delivery network의 약어이다.
여기서 content란 html, css, js, image files와 같은 정적 파일들을 말하고, 이 파일들을 전 세계에 위치해 있는 데이터 센터 network를 통해서 content를 deliver 한다.
장점
1. 물리적인 거리를 좁힌다.
S3 origin 서버를 대한민국 리전으로 생성했다고 가정해보자.
지구 반대편에 있는 유저들은 매 요청마다 한국에 위치한 S3 서버까지 해저 케이블을 통해 무선통신을 해야 한다. 물론 빛의 속도는 매우 빠르지만 물리적인 레이턴시가 필연적으로 발생하는데 CDN을 사용하면 전 세계에 proxy server를 두어 요청에 대한 응답 값들을 캐싱할 수 있다.
2. 트래픽을 분산시킨다
트래픽이 갑자기 몰릴 때 Origin 서버에 요청이 몰리는 것이 아니라 CDN 프록시 서버로 분산이 되기 때문에 오리진 서버의 트래픽 병목을 미연에 방지할 수 있다.
적용하기
2. 배포 생성
3. 원본 도메인은 사용 중인 Amazon Service Domain을 선택하자. (S3에 대한 도메인 이름을 선택)
4. 디폴트로 선택하고 배포 생성 클릭
매우 간단한 절차로 CDN 프록시 서버가 정상적으로 생성이 됐다.
앞으로의 요청은 원본 도메인 대신에 CloudFront 도메인으로 바꿔서 보내면 될 것이다.
한번 확인해보자
Cache Hit 확인
아래와 같이 CDN 도메인으로 변경한 후 요청을 보내고 네트워크 탭에서 Response Header를 살펴보자.
최초 요청은 Miss from cloudfront 이지만, 두 번째 요청부터는 CDN에 캐싱한다.
위 사진의 Response Headers에 x-cache: Hit from cloudfront 이 보인다.
AWS CloudFront로 S3 이미지 서버에 대한 CDN 설정을 완료했다. 이를 통해 우리 서버와, 전 세계 end user 간에 물리적인 위치를 줄였고, Origin 서버의 트래픽을 다중화하였다. 그런데 아직 Image optimization의 Best practice인 Image Reisizng이 남았다.
스포를 조금 하자면, 위 사진의 URL을 자세히 보자. 뒤에 w=120&h=120&q=80 이렇게 쿼리 파라미터가 붙어있는데, 이 인자를 통해 On fly 상태에서 run-time으로 이미지 크기를 조절(리사이징)함으로써 매우 적은 용량 크기로 이미지를 제공할 수 있다.
실제로 Sharp를 통한 이미지 리사이징을 현 서비스에 적용하여 용량을 최대 1000배 가량 줄일 수 있었고, 이로 인해 속도가 10배 이상 빨라졌다.
다음 글에서는 AWS의 serverless 서비스인 Lambda를 통해 실시간으로 이미지 리사이징하고 이를 CDN에 캐싱을 해보자.