Cloud CDN 문제 해결

Cloud CDN 사용 중에 문제가 발생할 경우 유용하게 활용할 수 있는 문제 해결 단계에 대해 알아보세요.

외부 백엔드와 관련된 문제인 경우 외부 백엔드 및 인터넷 NEG 문제 해결도 참조하세요.

일반적인 문제 및 해결 방법

응답이 캐시되지 않음

응답이 캐시되지 않는 경우 먼저 백엔드 서비스 또는 백엔드 버킷에 Cloud CDN을 사용하도록 설정되어 있는지 확인합니다. Cloud CDN을 사용하도록 설정하면 응답이 캐시되기 전에 몇 분 정도 걸릴 수 있습니다.

Cloud CDN은 캐시 가능한 콘텐츠가 있는 응답만 캐시합니다. 이 정보는 백엔드 구성과 함께 HTTP 응답 헤더를 통해 전달됩니다. URL에 대한 응답이 캐시되지 않는 경우, 해당 URL에 대해 반환되는 헤더를 확인하고 백엔드의 캐시 가능성 구성 방법을 확인합니다.

여러 가지 방법으로 응답 헤더를 확인할 수 있습니다.

다음 예시에서는 curl을 사용하여 http://example.com/style.css의 HTTP 응답 헤더를 확인하는 방법을 보여줍니다.

curl -s -D - -o /dev/null http://example.com/style.css

출력:

HTTP/1.1 200 OK
Date: Tue, 16 Feb 2016 12:00:00 GMT
Content-Type: text/css
Content-Length: 1977
Via: 1.1 google

이러한 헤더를 캐시 가능한 콘텐츠 요구사항과 비교하면 필수 Cache-Control 헤더(USE_ORIGIN_HEADERS로 설정된 캐시 모드가 있다고 가정)가 응답에서 누락되었음을 알 수 있습니다.

헤더 설정 방법은 원본 서버의 유형에 따라 다릅니다. Compute Engine에서 웹 서버를 실행하는 경우 응답 헤더 구성에 대한 자세한 내용은 웹 서버 소프트웨어 문서를 참조하세요. Cloud Storage의 경우 객체를 공개 공유로 표시하면 적절한 헤더가 전송됩니다.

원본 서버를 재구성하여 필수 헤더를 추가한 후에 curl을 다시 사용하여 결과를 확인할 수 있습니다.

curl -s -D - -o /dev/null http://example.com/style.css

출력:

HTTP/1.1 200 OK
Date: Tue, 16 Feb 2016 12:00:30 GMT
Content-Type: text/css
Content-Length: 1977
Cache-Control: max-age=86400,public
Via: 1.1 google
curl -s -D - -o /dev/null http://example.com/style.css

출력:

HTTP/1.1 200 OK
Date: Tue, 16 Feb 2016 12:00:31 GMT
Content-Type: text/css
Content-Length: 1977
Cache-Control: max-age=86400,public
Via: 1.1 google
curl -s -D - -o /dev/null http://example.com/style.css

출력:

HTTP/1.1 200 OK
Date: Tue, 16 Feb 2016 12:00:30 GMT
Content-Type: text/css
Content-Length: 1977
Cache-Control: max-age=86400,public
Via: 1.1 google
Age: 2

이 예시의 마지막 응답에는 Age 헤더가 포함됩니다. Cloud CDN은 캐시에서 제공하는 응답에 Age 헤더를 추가합니다. 여기에서 헤더는 2초 전에 생성된 캐시 항목을 사용하여 응답이 캐시에서 성공적으로 제공되었음을 나타냅니다.

또한 만일 백엔드 인스턴스에서 ETag가 사용 설정된 경우 Cloud CDN은 ETag를 사용하여 객체의 최신 상태를 확인합니다. 백엔드 인스턴스가 동일한 객체에 서로 다른 ETag를 제공하는 경우 Cloud CDN은 불일치를 캐시 부적중으로 계산하고 객체를 새로고침합니다. 이를 방지하려면 백엔드 인스턴스가 동일한 ETag를 제공해야 하거나 ETag를 사용 중지해야 합니다.

이를 확인하려면 curl을 반복 실행하고 ETag 값의 변화를 관찰합니다.

curl -s -D - -o /dev/null http://example.com/image.png

출력:

HTTP/2 200
date: Fri, 20 Mar 2020 15:02:30 GMT
server: Apache
strict-transport-security: max-age=31536000; includeSubDomains
last-modified: Mon, 16 Mar 2020 04:20:59 GMT
etag: "10f-5a0f1256f1402"
accept-ranges: bytes
content-length: 271
cache-control: public, max-age=864000
expires: Mon, 30 Mar 2020 15:02:30 GMT
vary: Accept-Encoding
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
content-type: image/png
via: 1.1 google
alt-svc: clear
curl -s -D - -o /dev/null http://example.com/image.png

출력:

HTTP/2 200
date: Fri, 20 Mar 2020 15:03:11 GMT
server: Apache
strict-transport-security: max-age=31536000; includeSubDomains
last-modified: Mon, 16 Mar 2020 04:18:31 GMT
etag: "10f-5a0f11ca09b7a"
accept-ranges: bytes
content-length: 271
cache-control: public, max-age=864000
expires: Mon, 30 Mar 2020 15:03:11 GMT
vary: Accept-Encoding
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
content-type: image/png
via: 1.1 google
alt-svc: clear

Cloud Storage 객체에 액세스할 수 없음

Cloud Storage의 객체에 대한 액세스를 제공하려면 서명된 URL을 구성하거나 버킷과 버킷의 모든 객체에 allUsers에 대한 공개 액세스 권한을 부여해야 합니다.

allUsers 액세스 권한을 부여하려면 다음에 따라 객체 수준 액세스를 확인하세요.

Console

  1. Google Cloud Console에서 Cloud Storage 브라우저를 엽니다.

    Storage 브라우저 열기

  2. 버킷 세부정보 페이지를 보려면 버킷을 클릭합니다.

  3. 공개 액세스 열에서 느낌표 아이콘에 마우스를 가져간 다음 액세스 권한 수정을 클릭합니다.

    버킷 내 각각의 객체에 대해 다음 권한이 설정되어 있는지 확인하세요.

    • 항목: User
    • 이름: allUsers
    • 액세스: Reader

Cloud Storage의 액세스 제어에 대해 자세히 알아보려면 Cloud Storage의 Identity and Access Management(IAM) 문서를 참조하세요.

서명된 URL에 대해 자세히 알아보려면 서명된 URL 사용을 참조하세요.

객체가 액세스 가능하나 캐시되고 있지는 않다면 응답이 캐시되지 않음을 참조하세요.

비공개 콘텐츠가 캐시되었거나 캐시된 콘텐츠가 잘못됨

원본 서버가 비공개 또는 잘못된 콘텐츠를 제공한 이유를 알고 있고 문제를 해결할 수 있는 경우 다음 프로세스를 사용하여 Cloud CDN 캐시를 무효화할 수 있습니다.

  1. 원본 서버가 더 이상 비공개 또는 잘못된 콘텐츠를 반환하지 않도록 합니다.
  2. 캐시 무효화를 요청하여 Cloud CDN이 캐시된 콘텐츠의 제공을 중지하도록 합니다.

자세한 내용은 캐시 무효화 개요를 참조하세요.

Cloud CDN은 캐시 가능한 콘텐츠가 있는 응답만 캐시하며 응답에 지정된 만료 시간까지만 캐시에서 응답을 제공합니다. 콘텐츠가 캐시된 이유를 모르거나 문제를 신속하게 해결할 수 없는 경우 문제를 파악하고 해결할 때까지 Cloud CDN을 사용 중지한 후 다시 사용 설정할 수 있습니다. 캐시되는 콘텐츠와 기간에 대한 자세한 내용은 캐싱 개요를 참조하세요.

캐시 적중률이 낮음

성능과 확장성을 위해 캐시 적중률을 최적화하는 것이 중요합니다. 캐시 적중률이 예상보다 낮은 경우 캐시 적중률을 최적화할 수 있는 권장사항을 따라야 합니다.

다음 표를 사용하여 캐시 적중률이 낮은 원인과 가능한 해결 방법을 알아봅니다.

이유 댓글 해결된 문제
캐시 가능한 콘텐츠가 없습니다. 캐시 가능한 응답은 Cloud CDN에서 저장할 수 있는 HTTP 응답입니다. 콘텐츠를 캐시할 수 있는지 확인합니다.
캐시 모드가 애플리케이션에 최적화되어 있지 않습니다. Cloud CDN에는 캐시 모드가 여러 개 있습니다. 캐시 제어 헤더를 사용하여 캐싱 동작을 제어하지 않는 경우 Cloud CDN에서 모든 정적 콘텐츠를 캐시하게 하는 것이 좋습니다.
트래픽이 소량 있습니다. 테스트 및 실험 중에 생성되는 트래픽 양이 적을 수 있습니다. Google에는 전역 분산 캐시가 있으며 서로 다른 지리적 위치에서의 요청은 다른 Google 프런트엔드 위치로 이동합니다. Google은 각 프런트엔드 위치에 캐시의 개별 인스턴스를 여러 개 가질 수 있습니다.
  • 모든 관련 캐시를 채울 수 있는 트래픽 양이 Google로 전송되고 있는지 확인합니다.
  • 테스트 중에 각 요청 집합의 모든 트래픽이 Google로 전달되도록 URL별로 트래픽을 샤딩해야 합니다. 각 요청을 여러 CDN 제공업체에 무작위로 샤딩하지 마세요.
특정 URL에 대한 응답은 캐시되지 않습니다. Cloud CDN은 전체 요청 URI를 캐시 키에 통합하므로 http://example.com/cat.jpg?color=orangehttp://example.com/cat.jpg?color=gray에는 별도의 캐시 항목이 있습니다. 항상 주어진 리소스에 단일 URL을 사용합니다.

캐시 가능한 페이지에서 실행 중인 자바스크립트에 매개변수를 전달해야 하는 경우에는 쿼리 문자열 대신 프래그먼트 식별자를 사용하는 것이 좋습니다.

Vary 헤더 필드로 인해 캐시가 불필요하게 샤딩됩니다. 응답의 Vary 헤더 필드는 메서드, Host 헤더 필드, 요청 대상 외에 요청 메시지의 어떤 부분에서 응답을 선택하고 표시할 수 있는 원본 서버의 프로세스에 영향을 줄 수 있는지 설명합니다. 예를 들어 압축된 응답을 처리할 수 있는 클라이언트와 처리할 수 없는 클라이언트에 서로 다른 콘텐츠를 제공하는 경우 Vary: Accept-Encoding 헤더를 사용하려 할 수 있습니다. 필요한 경우에만 Vary 응답 헤더를 사용합니다.
커스텀 캐시 키를 사용하지 않습니다. 기본적으로 Cloud CDN은 전체 요청 URL을 사용하여 캐시 키를 만듭니다. 캐시 키에서 프로토콜, 호스트, 쿼리 문자열의 조합을 포함하거나 생략하도록 맞춤설정할 수 있습니다. 예를 들어 두 도메인에서 같은 정적 콘텐츠를 사용하는 경우 호스트 필드를 생략하는 커스텀 캐시 키를 만들 수 있습니다. 필요한 경우 커스텀 캐시 키를 사용합니다.

동일한 콘텐츠에 대해 캐시 채우기가 여러 번 수행됨

일반적으로 캐시 가능한 응답의 만료 시간을 늘리면 캐시 채우기 횟수를 줄일 수 있습니다. 그 외의 모든 값이 같으면 Cache-Control: public, max-age=1 응답보다 Cache-Control: public, max-age=86400 응답에 대한 캐시 채우기가 더 적게 표시됩니다.

만료 시간에 대한 자세한 내용은 만료 시간 및 유효성 검사 요청을 참조하세요. 적절한 응답 헤더 구성에 대한 자세한 내용은 웹 서버 소프트웨어 문서를 참조하세요.

Cloud CDN은 전 세계에서 수많은 캐시를 운영하며 새 콘텐츠를 위한 공간을 확보하기 위해 오래된 캐시 항목은 정기적으로 삭제됩니다. 이로 인해 정상 작동의 일부로 리소스에 따른 캐시 채우기가 여러 번 수행됩니다.

압축이 작동하지 않음

Cloud CDN은 응답을 압축할 수 없는 원본에 동적 압축을 제공합니다. 가능하면 원본에서 압축을 사용하는 것이 좋습니다. 이렇게 하면 캐시 채우기 비용이 줄어들기 때문입니다.

Cloud CDN에서 제공되는 응답이 압축되지 않았지만 압축되어야 하는 경우, 인스턴스에서 실행 중인 웹 서버 소프트웨어가 응답을 압축하도록 구성되어 있는지 확인합니다. 기본적으로 일부 웹 서버 소프트웨어는 Via 헤더가 포함된 요청의 압축을 자동으로 중지합니다. Via 헤더가 있으면 요청이 프록시에 의해 전달되었다는 뜻입니다. 외부 애플리케이션 부하 분산기와 같은 HTTP 프록시는 HTTP 사양 요구에 따라 각 요청에 Via 헤더를 추가합니다. 압축을 사용 설정하려면 요청에 Via 헤더가 포함되었더라도 응답을 압축하도록 웹 서버의 기본 구성을 우선 적용해야 할 수 있습니다.

nginx 웹 서버 소프트웨어를 사용하는 경우 압축을 사용 설정하도록 nginx.conf 구성 파일을 수정합니다. 이 파일 위치는 nginx가 설치된 위치에 따라 달라집니다. 여러 Linux 배포판에서 이 파일은 /etc/nginx/nginx.conf에 저장됩니다.

nginx 압축이 외부 애플리케이션 부하 분산기와 함께 작동하도록 하려면 nginx.conf의 http 섹션에 다음 두 줄을 추가해야 합니다.

gzip_proxied any;
gzip_vary on;
  • 첫 번째 줄은 외부 애플리케이션 부하 분산기와 같은 프록시에 의해 전달된 요청도 압축하게 합니다.

  • 두 번째 줄은 응답에 Vary: Accept-Encoding 헤더를 추가합니다. Vary: Accept-Encoding은 압축 가능한 리소스의 압축 및 비압축 변형에 대해 별도의 캐시 항목을 유지해야 함을 Cloud CDN과 같은 캐싱 프록시에 알립니다.

nginx.conf를 수정한 후에는 새 구성을 사용하기 전에 nginx를 다시 시작해야 합니다. 여러 Linux 배포판에서 sudo service nginx restart 또는 /etc/init.d/nginx restart를 실행하여 nginx를 다시 시작할 수 있습니다.

응답이 byte_range_caching_aborted 오류로 종료됨

Cloud CDN은 여러 바이트 범위 요청의 응답을 어셈블할 때 ETagLast-Modified 응답 헤더를 비교하여 리소스의 동일한 버전에 해당 범위가 있는지 확인합니다. Cloud CDN은 이미 클라이언트에 제공된 범위와 두 헤더의 값이 하나라도 일치하지 않으면 응답을 중지합니다.

예기치 않게 종료된 응답, byte_range_caching_aborted statusDetails가 포함된 Cloud Logging 로그 항목 또는 412 Precondition Failed 응답이 반환된 인스턴스가 있는 경우 모든 가상 머신(VM) 인스턴스에서 실행 중인 웹 서버 소프트웨어가 제공된 리소스에 동일한 ETagLast-Modified 값을 반환하는지 확인합니다.

디스크에서 파일을 제공할 때 웹 서버 소프트웨어가 파일의 수정 시간에서 ETagLast-Modified 값을 파생하는 것이 일반적입니다. 이 경우 모든 인스턴스에 동일한 이미지를 사용하여 VM 인스턴스가 일관된 값을 보고하도록 할 수 있습니다. 웹 서버 소프트웨어가 ETagLast-Modified 값을 결정하는 방법에 대한 자세한 내용은 웹 서버 소프트웨어 문서를 참조하세요.

서명된 쿠키 문제 해결

서명된 쿠키를 사용할 때 다음과 같은 문제가 발생할 수 있습니다.

인코딩

서명을 생성할 때 서명 불일치로 인해 요청이 예기치 않게 거부됩니다.

URLSignature 값을 인코딩할 때 base64의 URL 보안 변형을 사용하고 있는지 확인합니다. 생성된 문자에 URL 보안이 적용되지 않은 경우 표준 base64가 실패합니다. 패딩이 허용됩니다.

서명

Cloud CDN에서 요청을 거부했습니다.

  • 다른 HMAC 변형이 아니라 HMAC-SHA-1을 서명 알고리즘으로 사용하고 있는지 확인합니다.

  • KeyName 매개변수(대소문자 구분)가 Cloud CDN에 사용되는 백엔드 서비스 또는 백엔드 버킷의 유효한 키 이름과 일치하는지 확인합니다.

  • URLPrefix를 생성하고 서명할 때 쿼리 매개변수에 서명하지 마세요. URLPrefix에 URL의 체계, 호스트, (부분) 경로 구성요소만 포함되어 있는지 확인합니다.

  • 서명 블록(URLPrefix, Expires, KeyName, Signature 자체)이 쿠키에서 마지막으로 :으로 구분된 섹션인지 확인합니다.

  • URLPrefix, Expires, KeyName, Signature가 이 순서대로 발생하는지 확인합니다.

  • 서명된 쿠키의 URLPrefix 끝에 별표(*) 문자를 포함하지 마세요.

쿠키

  • 브라우저는 일반적으로 쿠키를 도메인당 4KB로 제한하며 총 도메인당 쿠키 수는 50개로 제한됩니다. 많은 웹 서버에 최대 요청 헤더 제한이 있으므로 발급하고 클라이언트에서 보내도록 요구하는 다른 쿠키를 기록해 둡니다.

  • 서명된 매개변수의 구분자로 앰퍼샌드(&) 문자가 아닌 콜론 문자(:), 유니코드 코드 포인트(U+003A)를 사용하고 있는지 확인합니다.

  • 발급하는 쿠키의 Expires 타임스탬프가 불필요하게 짧지는 않은지 확인합니다. 유효성 검사 기간이 1~2분 미만이면 발급 앱과 Cloud CDN 인프라 간에 클럭 스큐 문제가 발생할 수 있습니다.

  • 동일한 DomainPath에 대해 서로 다른 값을 가진 여러 쿠키를 설정하지 않아야 합니다. 사용자가 액세스해야 하는 모든 콘텐츠를 포괄하는 URL 프리픽스 값으로 사용자당 하나의 쿠키를 설정합니다.

오류 메시지

캐시 무효화 오류

오류 코드 참고
Invalid value for field 'resource.path'

경로 값 형식이 잘못되었습니다. 경로는 /로 시작해야 하며 ? 또는 #를 포함할 수 없으며 *는 하나만 포함할 수 있고 이는 / 뒤에 오는 마지막 문자여야 합니다.

경로 길이는 1,024자를 넘지 않아야 합니다. 이 오류가 발생하면 경로 값을 확인하고 모든 형식 오류를 수정합니다.

이 오류는 경로 형식만 다룹니다. 올바른 형식이지만 존재하지 않는 경로는 여전히 유효한 경로로 간주됩니다.

Rate Limit Exceeded Cloud CDN은 캐시 무효화 작업을 수행할 수 있는 속도를 제한합니다. 무효화는 1분에 한 번만 허용됩니다. 그러나 각 작업에 객체 수와 일치하는 경로 패턴을 지정할 수 있습니다.

알려진 문제

  • 캐시 무효화는 1분에 URL 맵당 1회로 횟수가 제한됩니다.

    해결 방법: 1분 이상 기다린 후에 다른 URL 맵을 무효화하세요.

    캐시 무효화 비율 제한에 대한 자세한 내용은 제한사항을 참조하세요.