跳到內容

快取失效

編輯此頁面

「在電腦科學中,只有兩件難事:快取失效和命名。」-- Phil Karlton

一旦 URL 被閘道快取快取,快取將不再向應用程式請求該內容。這使得快取能夠提供快速回應並減少應用程式的負載。但是,您可能會面臨交付過時內容的風險。解決這個困境的方法是使用較長的快取生命週期,但在內容變更時主動通知閘道快取。反向代理通常提供一個通道來接收此類通知,通常透過特殊的 HTTP 請求。

警告

雖然快取失效功能強大,但請盡可能避免使用。如果您未能使某些內容失效,過時的快取可能會長時間被提供。相反地,請使用較短的快取生命週期或使用驗證模型,並調整您的控制器以執行有效的驗證檢查,如 HTTP 快取驗證 中所述。

此外,由於失效是一個特定於每種反向代理的主題,使用這個概念將會使您受限於特定的反向代理,或者需要額外的努力來支援不同的代理。

然而,有時您需要透過顯式失效來獲得額外的效能。為了進行失效,您的應用程式需要偵測內容何時變更,並告知快取移除包含該資料的 URL。

提示

如果您想使用快取失效,請查看 FOSHttpCacheBundle。此套件組提供了服務,以協助處理各種快取失效概念,並記錄了一些常見快取代理的設定。

如果一個內容對應到一個 URL,PURGE 模型運作良好。您可以使用 HTTP 方法 PURGE(使用 "PURGE" 這個詞是一個慣例,技術上可以是任何字串)而不是 GET 向快取代理發送請求,並讓快取代理偵測到這個請求,並從快取中移除資料,而不是前往應用程式取得回應。

以下是如何設定 Symfony 反向代理以支援 PURGE HTTP 方法。首先,建立一個快取核心,覆寫 invalidate() 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// src/CacheKernel.php
namespace App;

use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
// ...

class CacheKernel extends HttpCache
{
    protected function invalidate(Request $request, bool $catch = false): Response
    {
        if ('PURGE' !== $request->getMethod()) {
            return parent::invalidate($request, $catch);
        }

        if ('127.0.0.1' !== $request->getClientIp()) {
            return new Response(
                'Invalid HTTP method',
                Response::HTTP_BAD_REQUEST
            );
        }

        $response = new Response();
        if ($this->getStore()->purge($request->getUri())) {
            $response->setStatusCode(Response::HTTP_OK, 'Purged');
        } else {
            $response->setStatusCode(Response::HTTP_NOT_FOUND, 'Not found');
        }

        return $response;
    }
}

然後,將該類別註冊為裝飾 http_cache 的服務

1
2
3
4
5
6
7
8
9
10
11
12
13
// src/CacheKernel.php
namespace App;

// ...
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;

#[Autoconfigure(bind: ['$surrogate' => '@?esi'])]
#[AsDecorator(decorates: 'http_cache')]
class CacheKernel extends HttpCache
{
    // ...
}

危險

您必須以某種方式保護 PURGE HTTP 方法,以避免隨機人員清除您的快取資料。

Purge 指示快取丟棄資源的所有變體(根據 Vary 標頭,請參閱 HTTP 快取的變體回應)。Purge 的替代方案是重新整理內容。重新整理意味著指示快取代理丟棄其本地快取並再次取得內容。這樣一來,新內容已經在快取中可用。重新整理的缺點是變體不會失效。

在許多應用程式中,相同的內容位元被用於具有不同 URL 的各種頁面上。對於這些情況,存在更靈活的概念

  • 禁止使與 URL 或其他條件上的正則表達式匹配的回應失效;
  • 快取標記讓您可以為回應中使用的每個內容新增標籤,以便您可以使包含特定內容的所有 URL 失效。
本作品,包括程式碼範例,根據 Creative Commons BY-SA 3.0 授權條款授權。
目錄
    版本