CDN(Content Delivery Network) 약자 그대로 콘텐츠를 요청한 사용자가 있는 근접한 위치에 있는 서버에서 제공하기 위한 서비스입니다.
CDN을 이용하는 목적은 정말 많다고 생각합니다.
- 원본 서버의 트래픽 감소
- 빠른 콘텐츠 전송 속도 보장
- 별도의 캐시 서버 없이 기존 CDN 업체를 이용하면 구축하지 않아도 편리하게 사용 가능
- 미들 웨어 사용 시 미들웨어의 부담 감소
- 클라우드 사용 시 원본 서버 트래픽 비용보다 CDN을 활용한 OUTPUT 요금이 더 저렴한 경우가 있기 때문에 비용절감
그래서 다양한 CDN 서비스를 클라우드로 쉽게 설정할 수 있습니다.
그런데 이후 서비스를 사용하기 위해 몇 가지 작업을 해주어야 하는데 이러한 설명은 가이드에도 많이 없습니다. 그래서 적용 시 고려해볼 만한 사항을 정리해봅시다.
1. 요청 경로 도메인
네임서버의 A 레코드를 CDN 업체의 도메인 주소 또는 IP 주소로 변경해야 합니다.
하지만 DNS 서비스를 신청했을 때 IP를 제공해주지 않는 경우 nslookup을 통해 ip를 알아보거나 해당 업체에 통화해서 알아보아야 합니다. 아니면 CNAME을 사용하는 방법이 있습니다.
A 레코드와 CNAME 레코드 둘 다 같은 도메인에 등록되면 A 레코드에 등록된 정보를 우선적으로 제공하니 A 레코드 설정을 전부 해지하셔야 합니다. 이후 example.com에 대해 특정 CDN 도메인을 연결해 주어 모든 요청을 CDN으로 보낼 수 있습니다.
이러한 설정을 했다면 다음과 같은 예시들로 구성될 수 있습니다.
- www.example.com: 일반적인 웹 사이트의 주소입니다. 이 주소를 요청할 경우 CDN 서버를 거쳐 웹 서버로 요청이 전송됩니다.
- static.example.com: 만약 cname의 호스트를 static으로 구성하고 참조 주소를 cdn.example.com으로 지정했다면 static.example.com으로 요청하면 cdn.example.com으로 요청이 처리됩니다.
이는 정적 자원(이미지, CSS, JavaScript 등)을 저장된 주소입니다. 이 주소를 요청할 경우 CDN 서버에서 자원을 제공합니다. - cdn.example.com: CDN 서버의 주소입니다. 이 주소를 요청할 경우 CDN 서버로 요청이 전송됩니다.
다만 CDN의 주소로 요청을 매핑하게 되면 CDN에 SSL 인증서를 적용해주어야 합니다. 그래야 도메인 요청 시 SSL 적용이 됩니다.
2. html 파일 내부에서 정적 파일의 경로를 수정해주어야 한다.
만약 모든 정적 자원이 아닌 이미지, 동영상, 음성파일 등등 index.html에서 호출되는 콘텐츠에 대해서만 캐싱 서버에서 가져올 것이라면 다음과 같이 구성할 수 있습니다.
서버에게 index.html을 요청하게 되고 이후 CDN에게 요청해 콘텐츠를 내려받는 과정입니다.
이 과정에서 경로를 수정하지 않으면 원본 서버로 요청이 들어가게 됩니다.
CDN 서비스를 사용해서 index.html 파일을 받아왔는데 내부적으로 src=원본서버/image/a.jpg이라면 원본 서버로 요청이 가게 됩니다.
따라서 이러한 경로를 전부 cdn도메인으로 변경해주어야 합니다.
이러한 예시는 naver의 shoppinglive 홈페이지에서 찾아볼 수 있습니다.
거의 대부분의 이미지들을 별도의 cdn으로 요청하고 있습니다. 심지어 live streaming까지요
https://www.youtube.com/watch?v=XQKpHc2e59Y&t=791s
추가적으로 네이버에서 라이브 스트리밍을 위해 CDN을 활용한 사례를 소개하는 동영상입니다.
CDN은 원본 서버의 영향을 정말 많이 받습니다. 따라서 원본 서버에서도 적절한 설정이 필요합니다.
만약 CDN으로 웹 페이지를 제공하는 경우 실제 웹 서버에는 인증서를 적용하지 않아도 될 것입니다.
ssl 인증 과정은 생각보다 무겁기 때문인데요. 원본 서버와 cdn 간의 통신이 발생할 때 이는 http 요청을 통해 빠르게 처리하도록 개선할 수 있습니다.
또한 cache miss일 경우 cdn과 원본서버의 요청과 응답이 이루어지는데 이 경우 정적 파일에 대한 전송 과정이 필요합니다.
이를 bytes로 전달하는 것보단 원본 서버에서 gzip에 대한 설정을 해주어 압축된 콘텐츠 전송을 하도록 하면 동적 캐시를 사용하는 경우 성능이 개선될 수 있습니다.
이렇게 찾아보니 실제 Nginx 같은 웹 서버 소프트웨어가 어떻게 파일의 변경을 감지하는지 궁금해졌습니다.
CDN에 캐시 된 콘텐츠의 유효기간을 보통 설정하는데 원본 서버에서 전달해준 ‘Cache-Contorl: max-age, Expires 헤더의 값을 통해 콘텐츠의 유효성을 판단하거나, 설정 시 특정 시간을 통해 유횻값을 설정해 줍니다.
보통 max-age 헤더 값이 있으면 Expires 값은 무시됩니다.
실제 Nginx와 같은 서버가 실시간으로 파일을 감지하여 캐시를 재생성하여 전달하도록 하는 모듈이 있습니다.이는 리눅스 커널의 inotify 기능을 사용한 inotify_module이 존재합니다. 다만 이를 사용하기 위해서는 nginx 소스 코드를 다운로드하여 직접 컴파일할 수 있거나 이미 모듈이 포함된 이미지를 사용해야 합니다.
또한 리눅스 커널의 inotify기능이 켜져 있는지도 확인해야 하며 이후 Nginx에 별도의 설정을 해주어야 합니다.
얼핏 봐서는 매우 좋은 기능으로 보이지만 이는 매우 큰 리소스를 사용하게 합니다.
그 이유는 Nginx는 지속적으로 파일 시스템을 감시해야 하기 때문인데, 보통 이러한 기능을 사용하는 애플리케이션은 성능상 이슈때문에 버퍼에 일정 시간 모아 두고 알림을 주거나, 요청마다 개별 스레드를 통해 파일 변경 감지를 확인하도록 한다고 합니다.
따라서 보통 CDN에서는 purge라는 방법을 제공해주어 변경된 파일을 CDN에서 삭제하고 사용자가 요청 시 새로운 파일을 받을 수 있도록 합니다.
혹은 CDN의 정책 설정 시 Expires 값을 매우 짧게 주어서 정해진 시간마다 삭제하고 원본 서버에 요청하도록 할 수 있습니다.
하지만 이렇게 자주 변경되는 파일을 CDN을 통해 제공하는 것에 대해 고민해보아야 합니다.
정적 파일이라는 의미가 무색하게 자주 변경된다면 이는 처음부터 원본 서버에서 제공하는 것이 맞을 수 있습니다.
추가적으로 Nginx는 요청을 처리하기 위해 여러 개의 작업 스레드를 생성할 수 있습니다. 이러한 스레드를 "ETags"라고 합니다.
이는 HTTP 헤더의 일부로, 웹 서버가 제공하는 자원의 유일한 식별자로 사용될 수 있습니다.
웹 브라우저는 이를 통해 자원의 최신 상태를 확인할 수 있습니다.
이는 CDN과는 상관없는 이야기긴 한데, 응답 본문의 콘텐츠 내용이 변경되면 ETags의 값이 달라집니다.
그럼 브라우저가 내용 변경을 감지하고 캐시를 삭제합니다.
Nginx에서 etag on;이라는 설정을 통해 모든 자원에 대해 ETags 값을 생성하게 할 수 있습니다.
추가적으로 CDN을 이용할 시 고려해야 하는 사항이 있습니다.
서비스 요청 시 Query String을 사용할 경우에 대한 Cache 정책을 선택합니다.
- 원본 서버로 요청 시 사용자 요청의 Query String을 포함할지 선택할 수 있습니다. 원본 서버에서 Query String에 따라 다른 콘텐츠를 응답할 경우 별도의 캐시로 처리할 것 인지 확인해야 합니다.
원본에서의 Vary 헤더 응답에 대한 Cache 정책을 선택합니다.
- 만약 원본 서버에서 ‘Vary’ 헤더를 응답하지만 콘텐츠는 동일하다면 캐싱 효율을 위해 제거하는 것이 좋습니다. 원본에서 Vary 헤더를 응답하더라도 동일한 콘텐츠로 인식하기 위해 캐싱에서 제외할 수 있습니다.
- 콘텐츠가 다양한 버전으로 가지고 있으며 User-Agent, Referer, Cookie 등의 Vary 요청 헤더에 따라 응답 콘텐츠가 달라질 경우 별도의 캐시로 구성하도록 해야 합니다.
Vary 헤더는 HTTP 응답 헤더 중 하나로, 캐시 정책에 관련된 값을 지정합니다. Vary 헤더가 지정된 응답은 캐시 정책을 적용할 때 캐시 서버가 응답을 캐시 하기 전에 Vary 헤더가 지정한 값을 검사합니다.
Vary 헤더의 값으로는 일반적으로 "Accept-Encoding"과 같은 요청 헤더 이름을 지정할 수 있습니다.
이 경우 캐시 서버는 요청의 Accept-Encoding 헤더 값이 일치하는 응답을 캐시 합니다.
Vary 헤더를 지정하면 캐시 서버가 응답을 캐시 할 때 요청 헤더 값과 일치하는 응답을 캐시 하기 위해 요청 헤더 값을 검사하기 때문에, Vary 헤더가 지정된 응답은 전송 속도가 약간 느리게 될 수 있습니다.
예를 들어,
웹 서버가 응답에 Vary 헤더로 "Accept-Encoding"을 지정하고 있고, 요청에는 "Accept-Encoding: gzip"이 지정되어 있을 경우, 캐시 서버가 캐시 한 응답은 요청의 Accept-Encoding 헤더 값과 일치해야 합니다. 이는 캐시 서버가 캐시 한 응답을 전송할 때 요청 헤더 값과 일치하는 응답만 전송하기 위함입니다.
다른 예로, 웹 서버가 응답에 Vary 헤더로 "User-Agent"을 지정하고 있고, 요청에는 "User-Agent: Chrome"이 지정되어 있을 경우, 캐시 서버가 캐시한 응답은 요청의 User-Agent 헤더 값과 일치해야 합니다.
'느리게 변하는 지식' 카테고리의 다른 글
lambda in computer programming (0) | 2023.07.14 |
---|---|
타임존 (0) | 2022.12.06 |
아파치 웹 서버를 리눅스에서 설치할 때 왜 여러 패키지를 받을까? (0) | 2022.11.12 |
데드락 (0) | 2022.08.04 |
CPU 작동 원리 (0) | 2022.04.08 |
댓글