본문 바로가기

Dot Computer Science/Cloud

[Cloud] S3와 Cloudflare를 사용하여 웹 성능 개선하기 (CDN, 정적 콘텐츠 웹 호스팅)

    CDN

    CDN(Contents Delivery Network)은 웹 페이지, 이미지, 비디오 등의 정적 콘텐츠를 유저의 물리적 위치와 가까운 프록시 서버에 캐싱하여 전송 속도를 높여준다. 이들은 지리적으로 분산된 여러 개의 서버를 가지고 있다. 전 세계 데이터센터에 파일 복사본을 임시로 저장한다. 따라서 유저는 가까운 서버를 통해 콘텐츠가 로딩될 때까지 기다릴 필요 없이 영상 감상, 소프트웨어 다운로드, SNS 포스팅 등 다양한 작업을 원활하게 진행할 수 있다.

    서버 성능을 개선하기 위해서 가장 중요한 지표 2가지는 응답 시간과 처리량이다. 응답 시간 = 대기 시간 + 처리 시간이므로, 성능을 올리기 위해서 처리 시간 혹은 대기 시간을 줄여줘야 한다.

    • 처리 시간을 줄이기 위해서는 쿼리 튜닝, 캐시, 하드웨어 업그레이드 등의 방법이 있다.
    • 대기 시간을 줄이기 위해서는 응답 크기 줄이기, 트래픽 분리하기, 대역폭 늘리기 등이 있다.

    여기서 CDN은 트래픽을 분리해서 대기 시간을 줄여준다.

     

    대기 시간 감소

     

    AWS CloudFront vs Cloudflare

    대표적인 CDN 서비스로 AWS Cloudfront와 Cloudflare가 있다. 이 둘의 비교를 표로 정리해보면 다음과 같다. Cloudflare 프리 티어는 대역폭에 제한이 없다. 어떻게 무제한으로 제공할 수 있냐는 질문에 대한 Cloudflare CEO의 답변을 보면 여러 이유를 나열해놨지만 경쟁력을 높이고 홍보하기 위함이 커보인다.

     

      Cloudflare AWS CloudFront
    네트워크 아키텍처 리버스 프록시 전통적인 CDN
    기본 설정 방법 Nameserver Special URLs
    서버 개수 대략 150대 (21년 기준) 대략 140대 (21년 기준)
    주요 기능 CDN과 Ddos 방어 CDN
    마켓 포지셔닝 Standalone 플랫폼 AWS 클라우드 서비스 중 일부
    freetier 무제한 대역폭 비용 무료 매달 1TB 데이터 전송, 천만건 요청, 2백만건 함수 호출 무료 (참고)


    개인 프로젝트의 모든 클라우드 서비스를 AWS로 구성하였고 AWS Cloudfront 프리티어의 전송량도 충분하여 이를 쓰려고 했다. 그런데 CDN 서비스는 데이터 저장소처럼 이주가 어렵지 않기 때문에 마음에 안들면 언제든지 쉽게 서비스를 변경할 수 있다. 그래서 여러 이유로 인해 더 끌리는 Cloudflare를 먼저 사용해보기로 했다.

    먼저 Cloudflare는 연동이 매우 간단하다. DNS의 Nameserver만 변경해주면 된다. 그리고 무제한 대역폭 비용 무료이기 때문에 프리티어 요금 부과를 신경쓰지 않아도 되므로 훨씬 마음이 편하다. 그리고 선택에 가장 큰 비중을 차지한건 나중에 Cloudflare R2 저장소를 사용하고 싶었기 때문이다. (AWS Cloudfront에서도 사용이 가능한지는 아직 모르겠다.) 사실상 CDN을 사용하면서 과금이 가장 걱정되는 부분은 데이터 저장소(S3)의 데이터 전송 비용이다. 그런데 Cloudflare에서 출시 예정인 R2 저장소는 데이터 전송이 0원이다.

    S3

    • 프리티어 매달 5GB 스토리지, 20,000건 GET, 2,000 PUT, COPY, POST, LIST 요청까지
    • 1GB당 월 0.025$, 데이터 전송 GB당 0.126$ (참고)

    R2

     

    1. S3 버킷 생성하기

    버킷을 정적 웹 호스팅으로 사용하기 위해서는 다음과 같이 이름을 작성해줘야 한다 (참고)

    • domaineaxmple.com
    • www.domaineaxmple.com
    • cdn.domaineaxmple.com

     

    버킷 이름 입력


    버킷의 모든 퍼블릭 액세스 차단을 모두 해제해준다. 2)에서 직접 커스텀하여 설정해줄 것이기 때문이다.

     

    버킷 퍼블릭 액세스 차단 설정 해제

     

    2. S3 버킷 정책 설정 (Cloudflare 접근 허용하기)

    [버킷 > 권한 > 버킷 정책 > 편집]를 클릭하여 "GetObject" 정책을 Resource에 적용한다. 그리고 Cloudflare IP 주소를 허용하도록 설정해준다. 그러면 Cloudflare 프록시에서 오는 요청에만 응답하게 된다.

    • Resource: cdn.example.com/* 에 객체를 읽을 수 있는 "GetObject" 액션 권한을 추가한다.
    • Condition으로 Cloudflare IP 주소를 모두 허용하도록 설정해준다.
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "PublicReadGetObject",
                "Effect": "Deny",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::cdn.example.com/*",
                "Condition": {
                    "IpAddress": {
                        "aws:SourceIp": [
                            "2400:cb00::/32",
                            "2606:4700::/32",
                            "2803:f800::/32",
                            "2405:b500::/32",
                            "2405:8100::/32",
                            "2a06:98c0::/29",
                            "2c0f:f248::/32",
                            "173.245.48.0/20",
                            "103.21.244.0/22",
                            "103.22.200.0/22",
                            "103.31.4.0/22",
                            "141.101.64.0/18",
                            "108.162.192.0/18",
                            "190.93.240.0/20",
                            "188.114.96.0/20",
                            "197.234.240.0/22",
                            "198.41.128.0/17",
                            "162.158.0.0/15",
                            "172.64.0.0/13",
                            "131.0.72.0/22",
                            "104.16.0.0/13",
                            "104.24.0.0/14"
                        ]
                    }
                }
            }
        ]
    }

     

    3. 정적 웹 사이트 호스팅 활성화

    [버킷 > 속성 > 정적 웹 사이트 호스팅 > 편집]로 이동하여 호스팅 유형은 '정적 웹 사이트 호스팅'을 선택한다. 인덱스 문서는 기본적으로 'index.html'을 입력한다. 인덱스 문서 이름은 대소문자를 구분하며 S3 버킷에 업로드하려는 HTML 인덱스 문서의 파일 이름과 정확히 일치해야 한다. (참고)

     

    정적 웹 사이트 호스팅 활성화

     

    4. Cloudflare에 내 도메인 등록하기

    로그인한 후 [Home > Add a Site] 버튼을 클릭하고 사이트를 추가한다.

    1. 프리티어를 선택한다.
    2. Cloudflare의 2개 NameServer를 복사하여 기존 DNS를 Nameserver 4개를 지우고 해당 네임서버를 입력해준다. (혹시 몰라서 지우기 전 해당 값은 저장해놨다.)

     

    Cloudflare에 내 도메인 등록하기

     

    5. S3, Cloudflare 연동 완료

    그러면 길게는 1~2일 짧으면 몇 시간만에 연동이 완료된다. 그러면 Cloudflare에서 해당 사이트로 들어간 후 Https Only, Cache TTL 등 각종 설정을 앱 특성에 맞게 설정해주면 된다. 그러면 다음과 같이 무료로 트래픽도 측정해준다.

    • 저 첫 부분에 uncached request가 쌓인 부분은 Cloudflare에서 SSL/TLS 암호화모드를 'Flexible'로 바꿔보다가 리다이렉션이 엄청 발생하여 쌓인 것이다. JS나 CSS 중 절대 경로를 사용하는 게 있으면 안된다. 그래서 난 'Full'로 설정을 다시 바꿔줬다. (참고)
    • 그래서 두 번째에 정상적인 트래픽 결과에서는 cache된 비중이 더 높은 것을 볼 수 있다.
    • 그런데 사이트 검색 엔진을 등록하지도 않았는데 이스라엘, 러시아에서는 어떻게 들어오는 건지 모르겠다.

     

    Web Traffic

     

    웹 성능 개선 - CDN으로 트래픽 분산시켜 응답 시간 줄이기

    내가 만든 앱 특성상 인피니트 스크롤링으로 개발 콘텐츠를 보여주는 서비스이다보니 썸네일 이미지를 불러오는 횟수가 매우 많았다. 기존 버전에서는 썸네일 이미지를 Dataurl로 DB에 저장했기 때문에 이미지 로드되는 시간이 너무 길어서 UX가 자꾸 끊기는 현상이 발생했다. 인피니트 스크롤링으로 불러오는 페이징 쿼리의 응답 크기가 매우 커서 앱 성능 저하를 불러온 것이다.

     

    웹 서비스 성능을 개선시키기 위해 썸네일 이미지 파일을 S3에 저장하고 Cloudflare로 CDN을 사용하여 응답 트래픽을 분산시켜주는 방법을 선택했다. CDN이 적용되고 나서 실제로 웹 성능이 얼마나 개선되었는지, 응답시간이 얼마나 줄어들었는지 직접 Postman으로 확인해보자.

     

    1) CDN 적용 전 페이징 쿼리 응답 시간

    CDN 적용 전 DB에 저장된 12개의 게시글을 불러오는 페이징 쿼리 결과이다. 응답 크기가 너무 크다보니 시간도 408ms나 걸렸다.

    • 응답 시간: 408ms
    • 응답 크기: 6.31MB

    CDN 적용 전 페이징 쿼리 응답 결과

     

    2) CDN 적용 후 페이징 쿼리 응답 시간

    너무 느린 나머지 결국 DB 에서 저장된 dataUrl은 삭제하고 S3 썸네일을 저장한 url로 대체했다. S3에 썸네일 이미지를 저장하고 CDN으로 불러오는 로직으로 변경해줬다. 그리고 다시 쿼리를 실행해보니 CDN 적용 후 엄청나게 줄어든 것을 확인할 수 있었다. 무려 응답시간은 13.6배나 줄었고 응답 크기는 774배 정도 줄었다. 그리고 UX 끊김 현상도 일절 사라졌다.

    • 응답 시간: 408ms → 37ms (대략 13.6배 감소)
    • 응답 크기: 6310KB 8.15 KB (대략 774배 감소)

    CDN 적용 후 페이징 쿼리 응답 결과

     

    브라우저에서 [F12 > Network] 로 접속하여 정적 콘텐츠가 정상적으로 잘 전달되는 것을 확인할 수 있다.

     

     

    END.

    CDN을 도입해본 것은 처음인데 정말 좋은 기술인 것 같다. 연동도 매우 간단한데 그에 비해 얻는 성능 개선 효과도 뛰어나서 놀랐다. UX도 개선되고 서버와 유저간의 응답 트래픽도 줄어서 부하 발생 가능성도 줄어들게 되었다. 안그래도 Cloudflare CDN은 무료로 무제한 대역폭 제공해주는데 Cloudflare R2 스토리지가 나오면 전송 비용까지 무료이니 정말 인기가 많을 것 같다. 

     

     


    참고
    https://support.cloudflare.com/hc/en-us/articles/360037983412-Configuring-an-Amazon-Web-Services-static-site-to-use-Cloudflare
    https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/userguide/HostingWebsiteOnS3Setup.html
    https://www.techtarget.com/searchcloudcomputing/answer/Cloudflare-vs-Amazon-CloudFront-Which-CDN-is-right-for-you