2015-12-01 17 views
10

Ho configurato Symfony e FOSHttpCacheBundle (seguendo le istruzioni di configurazione di Varnish nello FOSHttpCache documentation).Come far funzionare Cache Tagging con FOSHttpCacheBundle e Varnish?

ho aggiunto un'azione per il mio controller che aggiunge un tag test nell'intestazione di risposta HTTP:

<?php 

use FOS\HttpCacheBundle\Configuration\Tag; 

class MyController extends Controller 
{ 
    /** 
    * @Route("/test1", name="acme_my_test1") 
    * @Tag("test") 
    */ 
    public function test1Action() 
    { 
     return new Response(rand(0, 1000)); 
    } 
} 

Tuttavia, ogni volta che io chiamo l'URL /test1, il numero cambia, mostrando la cache non è attiva. Si noti che la mia applicazione non utilizza alcun cookie e potrei verificare che l'intestazione X-Cache-Tags sia inviata a Varnish (che lo spoglia nella sua risposta al browser, grazie alla direttiva vlc_deliver).

C'è qualcosa che mi sarei perso nella configurazione? Sia Varnish che Nginx funzionano sullo stesso server.

Ecco la configurazione relativi alla cache HTTP nel mio file Symfony config.yml:

framework: 
    trusted_hosts: ~ 
    trusted_proxies: [127.0.0.1] 

fos_http_cache: 
    proxy_client: 
     varnish: 
      servers: 127.0.0.1:80 
      base_url: mywebsite.localhost.com 
    tags: 
     enabled: true 

e la configurazione Vernice in /etc/varnish/default.vcl:

vcl 4.0; 

backend default { 
    .host = "127.0.0.1"; 
    .port = "8080"; 
} 

acl invalidators { 
    "localhost"; 
} 

sub vcl_recv { 
    if (req.http.X-Forwarded-Proto == "https") { 
     set req.http.X-Forwarded-Port = "443"; 
    } else { 
     set req.http.X-Forwarded-Port = "80"; 
    } 

    set req.http.Surrogate-Capability = "abc=ESI/1.0"; 

    if (req.method == "PURGE") { 
     if (!client.ip ~ invalidators) { 
      return (synth(405, "Not allowed")); 
     } 
     return (purge); 
    } 

    if (req.http.Cache-Control ~ "no-cache" && client.ip ~ invalidators) { 
     set req.hash_always_miss = true; 
    } 

    if (req.method == "BAN") { 
     if (!client.ip ~ invalidators) { 
      return (synth(405, "Not allowed")); 
     } 

     if (req.http.X-Cache-Tags) { 
      ban("obj.http.X-Host ~ " + req.http.X-Host 
       + " && obj.http.X-Url ~ " + req.http.X-Url 
       + " && obj.http.content-type ~ " + req.http.X-Content-Type 
       + " && obj.http.X-Cache-Tags ~ " + req.http.X-Cache-Tags 
      ); 
     } else { 
      ban("obj.http.X-Host ~ " + req.http.X-Host 
       + " && obj.http.X-Url ~ " + req.http.X-Url 
       + " && obj.http.content-type ~ " + req.http.X-Content-Type 
      ); 
     } 

     return (synth(200, "Banned")); 
    } 
} 

sub vcl_backend_response { 
    set beresp.http.X-Url = bereq.url; 
    set beresp.http.X-Host = bereq.http.host; 

    if (beresp.http.Surrogate-Control ~ "ESI/1.0") { 
     unset beresp.http.Surrogate-Control; 
     set beresp.do_esi = true; 
    } 
} 

sub vcl_deliver { 
    if (!resp.http.X-Cache-Debug) { 
     unset resp.http.X-Url; 
     unset resp.http.X-Host; 
     unset resp.http.X-Cache-Tags; 
    } 
} 

risposta

5

Ok, l'ho trovato. Nella mia configurazione andava tutto bene tranne che dovevo aggiungere alcune intestazioni di scadenza. Pensavo che l'intestazione dei tag fosse sufficiente, ma sono necessari anche alcuni header di scadenza a lungo termine.

L'azione deve assomigliare a questo allora:

<?php 

use FOS\HttpCacheBundle\Configuration\Tag; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache; 

class MyController extends Controller 
{ 
    /** 
    * @Route("/test1", name="acme_my_test1") 
    * @Tag("test") 
    * @Cache(expires="+1 year") 
    */ 
    public function test1Action() 
    { 
     return new Response(rand(0, 1000)); 
    } 
} 

ho ancora un piccolo problema con i tag e tag ESI, ma questo è fuori dalla portata di questa domanda.