(frontend_cache_purging)= # 프런트엔드 캐시 무효화 많은 웹사이트는 Varnish, Squid, Cloudflare 또는 CloudFront와 같은 프런트엔드 캐시를 사용하여 추가 성능을 얻습니다. 그러나 프런트엔드 캐시를 사용하는 단점은 콘텐츠 업데이트에 잘 반응하지 않으며 페이지가 업데이트된 후에도 종종 페이지의 이전 버전을 캐시된 상태로 유지한다는 것입니다. 이 문서는 페이지가 업데이트될 때마다 프런트엔드 캐시에서 페이지의 이전 버전을 무효화하도록 Wagtail을 구성하는 방법을 설명합니다. ## 설정 먼저 `INSTALLED_APPS` 에 `"wagtail.contrib.frontend_cache"` 를 추가합니다. ```python INSTALLED_APPS = [ ... "wagtail.contrib.frontend_cache" ] ``` `wagtailfrontendcache` 모듈은 페이지가 게시되거나 삭제될 때마다 캐시를 자동으로 무효화하는 일련의 신호 핸들러를 제공합니다. 이러한 신호 핸들러는 `wagtail.contrib.frontend_cache` 앱이 로드될 때 자동으로 등록됩니다. ### Varnish/Squid `WAGTAILFRONTENDCACHE` 설정에 새 항목을 추가하고 `BACKEND` 매개변수를 `wagtail.contrib.frontend_cache.backends.HTTPBackend` 로 설정합니다. 이 백엔드에는 캐시가 실행 중인 위치를 가리키는 추가 매개변수 `LOCATION` 이 필요합니다(이는 서버에 대한 직접 연결이어야 하며 다른 프록시를 통과할 수 없습니다). ```python # 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 요청을 수락하도록 구성되었는지 확인하십시오. - [Varnish](https://varnish-cache.org/docs/3.0/tutorial/purging.html) - [Squid](https://wiki.squid-cache.org/SquidFaq/OperatingSquid#how-can-i-purge-an-object-from-my-cache) (frontendcache_cloudflare)= ### Cloudflare 먼저 Cloudflare 계정이 없는 경우 등록해야 합니다. 여기에서 할 수 있습니다: [Cloudflare 가입](https://dash.cloudflare.com/sign-up). `WAGTAILFRONTENDCACHE` 에 항목을 추가하고 `BACKEND` 매개변수를 `wagtail.contrib.frontend_cache.backends.CloudflareBackend` 로 설정합니다. 이 백엔드는 계정 전체 API 키 또는 제한된 액세스 권한이 있는 API 토큰을 사용하도록 구성할 수 있습니다. 계정 전체 API 키를 사용하려면 [Cloudflare 문서에 설명된 대로](https://developers.cloudflare.com/fundamentals/api/get-started/keys/#view-your-global-api-key) 키를 찾고 `EMAIL` 및 `API_KEY` 매개변수를 지정하십시오. 제한된 API 토큰을 사용하려면 'Zone, Cache Purge' 권한으로 [토큰을 생성](https://developers.cloudflare.com/api/get-started/create-token/)하고 `BEARER_TOKEN` 매개변수를 지정하십시오. 두 옵션 모두 `ZONEID` 매개변수를 설정해야 합니다. 도메인의 `ZONEID` 를 찾으려면 [Cloudflare API 문서](https://developers.cloudflare.com/fundamentals/get-started/basic-tasks/find-account-and-zone-ids/)를 읽으십시오. API 키 사용: ```python # 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 토큰 사용: ```python # settings.py WAGTAILFRONTENDCACHE = { 'cloudflare': { 'BACKEND': 'wagtail.contrib.frontend_cache.backends.CloudflareBackend', 'BEARER_TOKEN': 'your cloudflare bearer token', 'ZONEID': 'your cloudflare domain zone id', }, } ``` (frontendcache_aws_cloudfront)= ### Amazon CloudFront Amazon Web Services 내에 하나 이상의 CloudFront 웹 배포가 필요합니다. 없는 경우 여기에서 얻을 수 있습니다: [CloudFront 시작하기](https://aws.amazon.com/cloudfront/) `WAGTAILFRONTENDCACHE` 에 항목을 추가하고 `BACKEND` 매개변수를 `wagtail.contrib.frontend_cache.backends.CloudfrontBackend` 로 설정합니다. 이 백엔드에는 `DISTRIBUTION_ID`(CloudFront에서 생성된 배포 ID)라는 하나의 추가 매개변수가 필요합니다. ```python WAGTAILFRONTENDCACHE = { 'cloudfront': { 'BACKEND': 'wagtail.contrib.frontend_cache.backends.CloudfrontBackend', 'DISTRIBUTION_ID': 'your-distribution-id', }, } ``` `boto3` 는 자격 증명을 스스로 찾으려고 시도합니다. 자세한 내용은 여기에서 읽을 수 있습니다: [Boto 3 문서](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html). 사용자는 다음과 유사한 정책이 필요합니다: ```json { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowWagtailFrontendInvalidation", "Effect": "Allow", "Action": "cloudfront:CreateInvalidation", "Resource": "arn:aws:cloudfront:::distribution/" } ] } ``` 자격 증명을 수동으로 지정하려면 추가 매개변수로 전달하십시오: ```python 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](https://azure.microsoft.com/en-gb/products/cdn/)을 사용하려면 엔드포인트가 구성된 CDN 프로필이 필요합니다. 이 백엔드의 타사 종속성은 다음과 같습니다: | PyPI 패키지 | 필수 | 이유 | | ---------------------------------------------------------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | [`azure-mgmt-cdn`](https://pypi.org/project/azure-mgmt-cdn/) | 예 (v10.0 이상) | CDN 서비스와 상호 작용합니다. | | [`azure-identity`](https://pypi.org/project/azure-identity/) | 아니요 | 자격 증명 획득. `CREDENTIALS` 설정을 사용하여 자체 자격 증명을 지정하려는 경우 선택 사항입니다(자세한 내용은 아래 참조). | | [`azure-mgmt-resource`](https://pypi.org/project/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` - 무효화하려는 엔드포인트의 이름. ```python 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 문서](https://learn.microsoft.com/en-us/azure/developer/python/sdk/authentication-overview)에서 옵션에 대해 읽어보십시오. ```python 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](https://azure.microsoft.com/en-gb/products/frontdoor/)를 사용하려면 캐싱이 활성화된 Front Door 인스턴스가 필요합니다. 이 백엔드의 타사 종속성은 다음과 같습니다: | PyPI 패키지 | 필수 | 이유 | | ------------------------------------------------------------------------ | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | [`azure-mgmt-frontdoor`](https://pypi.org/project/azure-mgmt-frontdoor/) | 예 (v1.0 이상) | Front Door 서비스와 상호 작용합니다. | | [`azure-identity`](https://pypi.org/project/azure-identity/) | 아니요 | 자격 증명 획득. `CREDENTIALS` 설정을 사용하여 자체 자격 증명을 지정하려는 경우 선택 사항입니다(자세한 내용은 아래 참조). | | [`azure-mgmt-resource`](https://pypi.org/project/azure-mgmt-resource/) | 아니요 | 구독 ID 획득. `SUBSCRIPTION_ID` 설정을 명시적으로 지정하려는 경우 중복됩니다(자세한 내용은 아래 참조). | `WAGTAILFRONTENDCACHE` 에 항목을 추가하고 `BACKEND` 매개변수를 `wagtail.contrib.frontend_cache.backends.AzureFrontDoorBackend` 로 설정합니다. 이 백엔드에는 다음 설정이 필요합니다: - `RESOURCE_GROUP_NAME` - Front Door 인스턴스가 속한 리소스 그룹. - `FRONT_DOOR_NAME` - 구성된 Front Door 인스턴스 이름. ```python 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 문서](https://learn.microsoft.com/en-us/azure/developer/python/sdk/authentication-overview)에서 옵션에 대해 읽어보십시오. ```python 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` 입니다. 기본적으로 처음 발견된 구독이 사용되지만, 자격 증명이 더 많은 구독에 액세스할 수 있는 경우 이를 명시적 값으로 설정해야 합니다. (frontendcache_multiple_backends)= ## 여러 백엔드 `WAGTAILFRONTENDCACHE` 에 여러 항목을 추가하여 여러 백엔드를 구성할 수 있습니다. 기본적으로 백엔드는 모든 무효화 요청을 무효화하려고 시도합니다. 특정 호스트 이름만 무효화하려면 `HOSTNAMES` 에 지정하십시오. ```python 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` 를 변경하는 방식입니다. ```python 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'] }, } ``` ```{note} 대부분의 경우 `www` 접두사가 붙은 도메인 이름이 있는 절대 URL을 매핑에 사용해야 합니다. `www` 접두사를 사용하지 않는 것이 확실한 경우에만(예: 서브도메인) `www` 접두사를 삭제하십시오. ``` Django의 `ALLOWED_HOSTS` 와 마찬가지로 `HOSTNAMES` 의 `.` 으로 시작하는 값은 서브도메인 와일드카드로 사용할 수 있습니다. ## 고급 사용법 ### 페이지당 두 개 이상의 URL 무효화 기본적으로 Wagtail은 페이지당 하나의 URL만 무효화합니다. 페이지에 무효화할 URL이 두 개 이상인 경우 페이지 유형에서 `get_cached_paths` 메서드를 재정의해야 합니다. ```python 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` 클래스를 사용하여 색인 페이지의 무효화를 트리거합니다. ```python # 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) ``` (frontend_cache_invalidating_urls)= ### URL 무효화 `PurgeBatch` 클래스는 무효화 배치에 개별 URL을 추가하기 위한 `.add_url(url)` 및 `.add_urls(urls)` 를 제공합니다. 예를 들어, 블로그 색인의 단일 페이지를 무효화하는 데 유용할 수 있습니다. ```python from wagtail.contrib.frontend_cache.utils import PurgeBatch # 블로그 색인의 첫 페이지 무효화 batch = PurgeBatch() batch.add_url(blog_index.url + '?page=1') batch.purge() ``` ### `PurgeBatch` 클래스 `PurgeBatch` 에서 사용할 수 있는 모든 메서드는 다음과 같습니다. ```{eval-rst} .. automodule:: wagtail.contrib.frontend_cache.utils .. autoclass:: PurgeBatch .. automethod:: add_url .. automethod:: add_urls .. automethod:: add_page .. automethod:: add_pages .. automethod:: purge ```