프런트엔드 캐시 무효화¶
많은 웹사이트는 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_I18N 이 True 여야 합니다. 기본값은 빈 목록입니다.
마지막으로, 프런트엔드 캐시가 PURGE 요청을 수락하도록 구성되었는지 확인하십시오.
Cloudflare¶
먼저 Cloudflare 계정이 없는 경우 등록해야 합니다. 여기에서 할 수 있습니다: Cloudflare 가입.
WAGTAILFRONTENDCACHE 에 항목을 추가하고 BACKEND 매개변수를 wagtail.contrib.frontend_cache.backends.CloudflareBackend 로 설정합니다.
이 백엔드는 계정 전체 API 키 또는 제한된 액세스 권한이 있는 API 토큰을 사용하도록 구성할 수 있습니다.
계정 전체 API 키를 사용하려면 Cloudflare 문서에 설명된 대로 키를 찾고 EMAIL 및 API_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 패키지 |
필수 |
이유 |
|---|---|---|
예 (v10.0 이상) |
CDN 서비스와 상호 작용합니다. |
|
아니요 |
자격 증명 획득. |
|
아니요 |
구독 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 패키지 |
필수 |
이유 |
|---|---|---|
예 (v1.0 이상) |
Front Door 서비스와 상호 작용합니다. |
|
아니요 |
자격 증명 획득. |
|
아니요 |
구독 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/foo 는 main-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_published 및 page_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