프런트엔드 캐시 무효화

많은 웹사이트는 Varnish, Squid, Cloudflare 또는 CloudFront와 같은 프런트엔드 캐시를 사용하여 추가 성능을 얻습니다. 그러나 프런트엔드 캐시를 사용하는 단점은 콘텐츠 업데이트에 잘 반응하지 않으며 페이지가 업데이트된 후에도 종종 페이지의 이전 버전을 캐시된 상태로 유지한다는 것입니다.

이 문서는 페이지가 업데이트될 때마다 프런트엔드 캐시에서 페이지의 이전 버전을 무효화하도록 Wagtail을 구성하는 방법을 설명합니다.

설정

먼저 INSTALLED_APPS"wagtail.contrib.frontend_cache" 를 추가합니다.

INSTALLED_APPS = [
    ...

    "wagtail.contrib.frontend_cache"
]

wagtailfrontendcache 모듈은 페이지가 게시되거나 삭제될 때마다 캐시를 자동으로 무효화하는 일련의 신호 핸들러를 제공합니다. 이러한 신호 핸들러는 wagtail.contrib.frontend_cache 앱이 로드될 때 자동으로 등록됩니다.

Varnish/Squid

WAGTAILFRONTENDCACHE 설정에 새 항목을 추가하고 BACKEND 매개변수를 wagtail.contrib.frontend_cache.backends.HTTPBackend 로 설정합니다. 이 백엔드에는 캐시가 실행 중인 위치를 가리키는 추가 매개변수 LOCATION 이 필요합니다(이는 서버에 대한 직접 연결이어야 하며 다른 프록시를 통과할 수 없습니다).

# settings.py

WAGTAILFRONTENDCACHE = {
    'varnish': {
        'BACKEND': 'wagtail.contrib.frontend_cache.backends.HTTPBackend',
        'LOCATION': 'http://localhost:8000',
    },
}
WAGTAILFRONTENDCACHE_LANGUAGES = []

WAGTAILFRONTENDCACHE_LANGUAGES 를 언어 목록(일반적으로 [l[0] for l in settings.LANGUAGES] 와 같음)으로 설정하여 무효화 URL의 각 언어에 대한 URL도 무효화합니다. 이 설정은 작동하려면 settings.USE_I18NTrue 여야 합니다. 기본값은 빈 목록입니다.

마지막으로, 프런트엔드 캐시가 PURGE 요청을 수락하도록 구성되었는지 확인하십시오.

Cloudflare

먼저 Cloudflare 계정이 없는 경우 등록해야 합니다. 여기에서 할 수 있습니다: Cloudflare 가입.

WAGTAILFRONTENDCACHE 에 항목을 추가하고 BACKEND 매개변수를 wagtail.contrib.frontend_cache.backends.CloudflareBackend 로 설정합니다.

이 백엔드는 계정 전체 API 키 또는 제한된 액세스 권한이 있는 API 토큰을 사용하도록 구성할 수 있습니다.

계정 전체 API 키를 사용하려면 Cloudflare 문서에 설명된 대로 키를 찾고 EMAILAPI_KEY 매개변수를 지정하십시오.

제한된 API 토큰을 사용하려면 ‘Zone, Cache Purge’ 권한으로 토큰을 생성하고 BEARER_TOKEN 매개변수를 지정하십시오.

두 옵션 모두 ZONEID 매개변수를 설정해야 합니다. 도메인의 ZONEID 를 찾으려면 Cloudflare API 문서를 읽으십시오.

API 키 사용:

# settings.py

WAGTAILFRONTENDCACHE = {
    'cloudflare': {
        'BACKEND': 'wagtail.contrib.frontend_cache.backends.CloudflareBackend',
        'EMAIL': 'your-cloudflare-email-address@example.com',
        'API_KEY': 'your cloudflare api key',
        'ZONEID': 'your cloudflare domain zone id',
    },
}

API 토큰 사용:

# settings.py

WAGTAILFRONTENDCACHE = {
    'cloudflare': {
        'BACKEND': 'wagtail.contrib.frontend_cache.backends.CloudflareBackend',
        'BEARER_TOKEN': 'your cloudflare bearer token',
        'ZONEID': 'your cloudflare domain zone id',
    },
}

Amazon CloudFront

Amazon Web Services 내에 하나 이상의 CloudFront 웹 배포가 필요합니다. 없는 경우 여기에서 얻을 수 있습니다: CloudFront 시작하기

WAGTAILFRONTENDCACHE 에 항목을 추가하고 BACKEND 매개변수를 wagtail.contrib.frontend_cache.backends.CloudfrontBackend 로 설정합니다. 이 백엔드에는 DISTRIBUTION_ID(CloudFront에서 생성된 배포 ID)라는 하나의 추가 매개변수가 필요합니다.

WAGTAILFRONTENDCACHE = {
    'cloudfront': {
        'BACKEND': 'wagtail.contrib.frontend_cache.backends.CloudfrontBackend',
        'DISTRIBUTION_ID': 'your-distribution-id',
    },
}

boto3 는 자격 증명을 스스로 찾으려고 시도합니다. 자세한 내용은 여기에서 읽을 수 있습니다: Boto 3 문서. 사용자는 다음과 유사한 정책이 필요합니다:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowWagtailFrontendInvalidation",
            "Effect": "Allow",
            "Action": "cloudfront:CreateInvalidation",
            "Resource": "arn:aws:cloudfront::<account id>:distribution/<distribution id>"
        }
    ]
}

자격 증명을 수동으로 지정하려면 추가 매개변수로 전달하십시오:

WAGTAILFRONTENDCACHE = {
    'cloudfront': {
        'BACKEND': 'wagtail.contrib.frontend_cache.backends.CloudfrontBackend',
        'DISTRIBUTION_ID': 'your-distribution-id',
        'AWS_ACCESS_KEY_ID': os.environ['FRONTEND_CACHE_AWS_ACCESS_KEY_ID'],
        'AWS_SECRET_ACCESS_KEY': os.environ['FRONTEND_CACHE_AWS_SECRET_ACCESS_KEY'],
        'AWS_SESSION_TOKEN': os.environ['FRONTEND_CACHE_AWS_SESSION_TOKEN']
    },
}

Azure CDN

Azure CDN을 사용하려면 엔드포인트가 구성된 CDN 프로필이 필요합니다.

이 백엔드의 타사 종속성은 다음과 같습니다:

PyPI 패키지

필수

이유

azure-mgmt-cdn

예 (v10.0 이상)

CDN 서비스와 상호 작용합니다.

azure-identity

아니요

자격 증명 획득. CREDENTIALS 설정을 사용하여 자체 자격 증명을 지정하려는 경우 선택 사항입니다(자세한 내용은 아래 참조).

azure-mgmt-resource

아니요

구독 ID 획득. SUBSCRIPTION_ID 설정을 명시적으로 지정하려는 경우 중복됩니다(자세한 내용은 아래 참조).

WAGTAILFRONTENDCACHE 에 항목을 추가하고 BACKEND 매개변수를 wagtail.contrib.frontend_cache.backends.AzureCdnBackend 로 설정합니다. 이 백엔드에는 다음 설정이 필요합니다:

  • RESOURCE_GROUP_NAME - CDN 프로필이 있는 리소스 그룹.

  • CDN_PROFILE_NAME - 사용하려는 CDN 서비스의 프로필 이름.

  • CDN_ENDPOINT_NAME - 무효화하려는 엔드포인트의 이름.

    WAGTAILFRONTENDCACHE = {
        'azure_cdn': {
            'BACKEND': 'wagtail.contrib.frontend_cache.backends.AzureCdnBackend',
            'RESOURCE_GROUP_NAME': 'MY-WAGTAIL-RESOURCE-GROUP',
            'CDN_PROFILE_NAME': 'wagtailio',
            'CDN_ENDPOINT_NAME': 'wagtailio-cdn-endpoint-123',
        },
    }

기본적으로 자격 증명은 azure.identity.DefaultAzureCredential 을 사용합니다. 사용되는 자격 증명 개체를 수정하려면 CREDENTIALS 설정을 사용하십시오. Azure 문서에서 옵션에 대해 읽어보십시오.

from azure.common.credentials import ServicePrincipalCredentials

WAGTAILFRONTENDCACHE = {
    'azure_cdn': {
        'BACKEND': 'wagtail.contrib.frontend_cache.backends.AzureCdnBackend',
        'RESOURCE_GROUP_NAME': 'MY-WAGTAIL-RESOURCE-GROUP',
        'CDN_PROFILE_NAME': 'wagtailio',
        'CDN_ENDPOINT_NAME': 'wagtailio-cdn-endpoint-123',
        'CREDENTIALS': ServicePrincipalCredentials(
            client_id='your client id',
            secret='your client secret',
        )
    },
}

설정할 수 있는 또 다른 옵션은 SUBSCRIPTION_ID 입니다. 기본적으로 처음 발견된 구독이 사용되지만, 자격 증명이 더 많은 구독에 액세스할 수 있는 경우 이를 명시적 값으로 설정해야 합니다.

Azure Front Door

Azure Front Door를 사용하려면 캐싱이 활성화된 Front Door 인스턴스가 필요합니다.

이 백엔드의 타사 종속성은 다음과 같습니다:

PyPI 패키지

필수

이유

azure-mgmt-frontdoor

예 (v1.0 이상)

Front Door 서비스와 상호 작용합니다.

azure-identity

아니요

자격 증명 획득. CREDENTIALS 설정을 사용하여 자체 자격 증명을 지정하려는 경우 선택 사항입니다(자세한 내용은 아래 참조).

azure-mgmt-resource

아니요

구독 ID 획득. SUBSCRIPTION_ID 설정을 명시적으로 지정하려는 경우 중복됩니다(자세한 내용은 아래 참조).

WAGTAILFRONTENDCACHE 에 항목을 추가하고 BACKEND 매개변수를 wagtail.contrib.frontend_cache.backends.AzureFrontDoorBackend 로 설정합니다. 이 백엔드에는 다음 설정이 필요합니다:

  • RESOURCE_GROUP_NAME - Front Door 인스턴스가 속한 리소스 그룹.

  • FRONT_DOOR_NAME - 구성된 Front Door 인스턴스 이름.

WAGTAILFRONTENDCACHE = {
    'azure_front_door': {
        'BACKEND': 'wagtail.contrib.frontend_cache.backends.AzureFrontDoorBackend',
        'RESOURCE_GROUP_NAME': 'MY-WAGTAIL-RESOURCE-GROUP',
        'FRONT_DOOR_NAME': 'wagtail-io-front-door',
    },
}

기본적으로 자격 증명은 azure.identity.DefaultAzureCredential 을 사용합니다. 사용되는 자격 증명 개체를 수정하려면 CREDENTIALS 설정을 사용하십시오. Azure 문서에서 옵션에 대해 읽어보십시오.

from azure.common.credentials import ServicePrincipalCredentials

WAGTAILFRONTENDCACHE = {
    'azure_front_door': {
        'BACKEND': 'wagtail.contrib.frontend_cache.backends.AzureFrontDoorBackend',
        'RESOURCE_GROUP_NAME': 'MY-WAGTAIL-RESOURCE-GROUP',
        'FRONT_DOOR_NAME': 'wagtail-io-front-door',
        'CREDENTIALS': ServicePrincipalCredentials(
            client_id='your client id',
            secret='your client secret',
        )
    },
}

설정할 수 있는 또 다른 옵션은 SUBSCRIPTION_ID 입니다. 기본적으로 처음 발견된 구독이 사용되지만, 자격 증명이 더 많은 구독에 액세스할 수 있는 경우 이를 명시적 값으로 설정해야 합니다.

여러 백엔드

WAGTAILFRONTENDCACHE 에 여러 항목을 추가하여 여러 백엔드를 구성할 수 있습니다.

기본적으로 백엔드는 모든 무효화 요청을 무효화하려고 시도합니다. 특정 호스트 이름만 무효화하려면 HOSTNAMES 에 지정하십시오.

WAGTAILFRONTENDCACHE = {
    'main-site': {
        'BACKEND': 'wagtail.contrib.frontend_cache.backends.HTTPBackend',
        'LOCATION': 'http://localhost:8000',
        'HOSTNAMES': ['example.com']
    },
    'cdn': {
        'BACKEND': 'wagtail.contrib.frontend_cache.backends.CloudflareBackend',
        'BEARER_TOKEN': 'your cloudflare bearer token',
        'ZONEID': 'your cloudflare domain zone id',
        'HOSTNAMES': ['cdn.example.com']
    },
}

위 예시에서 cdn.example.com/foo 에 대한 무효화는 Cloudflare에 의해 무효화되는 반면, example.com/foomain-site 백엔드로 무효화됩니다. 이를 통해 각 백엔드에 다른 구성을 사용할 수 있습니다. 예를 들어 Cloudflare 백엔드의 ZONEID 를 변경하는 방식입니다.


WAGTAILFRONTENDCACHE = {
    'main-site': {
        'BACKEND': 'wagtail.contrib.frontend_cache.backends.CloudflareBackend',
        'BEARER_TOKEN': os.environ["CLOUDFLARE_BEARER_TOKEN"],
        'ZONEID': 'example.com zone id',
        'HOSTNAMES': ['example.com']
    },
    'other-site': {
        'BACKEND': 'wagtail.contrib.frontend_cache.backends.CloudflareBackend',
        'BEARER_TOKEN': os.environ["CLOUDFLARE_BEARER_TOKEN"],
        'ZONEID': 'example.net zone id',
        'HOSTNAMES': ['example.net']
    },
}

참고

대부분의 경우 www 접두사가 붙은 도메인 이름이 있는 절대 URL을 매핑에 사용해야 합니다. www 접두사를 사용하지 않는 것이 확실한 경우에만(예: 서브도메인) www 접두사를 삭제하십시오.

Django의 ALLOWED_HOSTS 와 마찬가지로 HOSTNAMES. 으로 시작하는 값은 서브도메인 와일드카드로 사용할 수 있습니다.

고급 사용법

페이지당 두 개 이상의 URL 무효화

기본적으로 Wagtail은 페이지당 하나의 URL만 무효화합니다. 페이지에 무효화할 URL이 두 개 이상인 경우 페이지 유형에서 get_cached_paths 메서드를 재정의해야 합니다.

class BlogIndexPage(Page):
    def get_blog_items(self):
        # 이 섹션의 블로그 항목에 대한 Django 페이지네이터를 반환합니다.
        return Paginator(self.get_children().live().type(BlogPage), 10)

    def get_cached_paths(self):
        # 기본 URL 반환
        yield '/'

        # 모든 페이지가 무효화되도록 페이지네이터의 페이지당 하나의 URL 반환
        for page_number in range(1, self.get_blog_items().num_pages + 1):
            yield '/?page=' + str(page_number)

색인 페이지 무효화

다른 페이지를 나열하는 페이지(예: 블로그 색인)도 무효화해야 할 수 있으므로 블로그 페이지에 대한 변경 사항도 색인에 반영됩니다(예: 블로그 게시물이 추가, 삭제되거나 제목/썸네일이 변경됨).

이러한 페이지를 무효화하려면 블로그 페이지에 대한 Wagtail의 page_publishedpage_unpublished 신호를 수신하는 신호 핸들러를 작성해야 합니다. (참고, page_published 는 페이지가 생성되고 업데이트될 때 모두 호출됩니다.) 이 신호 핸들러는 무효화 요청을 구성하고 디스패치하는 데 사용되는 PurgeBatch 클래스를 사용하여 색인 페이지의 무효화를 트리거합니다.

# models.py
from django.dispatch import receiver
from django.db.models.signals import pre_delete

from wagtail.signals import page_published
from wagtail.contrib.frontend_cache.utils import PurgeBatch

...

def blog_page_changed(blog_page):
    # 이 blog_page를 포함하는 모든 라이브 BlogIndexPage 찾기
    batch = PurgeBatch()
    for blog_index in BlogIndexPage.objects.live():
        if blog_page in blog_index.get_blog_items().object_list:
            batch.add_page(blog_index)

    # 찾은 모든 블로그 색인을 단일 요청으로 무효화
    batch.purge()


@receiver(page_published, sender=BlogPage)
def blog_published_handler(instance, **kwargs):
    blog_page_changed(instance)


@receiver(pre_delete, sender=BlogPage)
def blog_deleted_handler(instance, **kwargs):
    blog_page_changed(instance)

URL 무효화

PurgeBatch 클래스는 무효화 배치에 개별 URL을 추가하기 위한 .add_url(url).add_urls(urls) 를 제공합니다.

예를 들어, 블로그 색인의 단일 페이지를 무효화하는 데 유용할 수 있습니다.

from wagtail.contrib.frontend_cache.utils import PurgeBatch

# 블로그 색인의 첫 페이지 무효화
batch = PurgeBatch()
batch.add_url(blog_index.url + '?page=1')
batch.purge()

PurgeBatch 클래스

PurgeBatch 에서 사용할 수 있는 모든 메서드는 다음과 같습니다.

class wagtail.contrib.frontend_cache.utils.PurgeBatch(urls=None, *, cache_object=None)

Represents a list of URLs to be purged in a single request

add_url(url)

Adds a single URL

add_urls(urls)

Adds multiple URLs from an iterable

This is equivalent to running .add_url(url) on each URL individually

add_page(page)

Adds all URLs for the specified page

This combines the page’s full URL with each path that is returned by the page’s .get_cached_paths method

add_pages(pages)

Adds multiple pages from a QuerySet or an iterable

This is equivalent to running .add_page(page) on each page individually

purge(backend_settings=None, backends=None)

Performs the purge of all the URLs in this batch

This method takes two optional keyword arguments: backend_settings and backends

  • backend_settings can be used to override the WAGTAILFRONTENDCACHE setting for just this call

  • backends can be set to a list of backend names. When set, the invalidation request will only be sent to these backends