2012-04-23 11 views
21

Recentemente ho aggiunto un'istanza di Varnish a uno stack di applicazioni Rails. Varnish nella sua configurazione di default può essere convinto dalla cache una certa risorsa utilizzando l'intestazione Cache-Control in questo modo:Come controllare Varnish e un browser usando Cache-Control: max-age Header in un ambiente Rails?

Cache-Control: max-age=86400, public=true 

ho raggiunto quella utilizzando l'istruzione expires_in nei miei controllori:

def index 
    expires_in 24.hours, public: true 
    respond_with 'some content' 
end 

che ha funzionato bene. Quello che non mi aspettavo è che l'intestazione Cache-Control abbia effetto sul browser. Ciò porta al problema che entrambi - Varnish e il browser degli utenti memorizzano nella cache una determinata risorsa. La risorsa viene eliminata correttamente dalla vernice, ma il browser non tenta di richiederlo nuovamente a meno che non venga raggiunto il limite massimo di età.

Quindi mi chiedo se dovrei usare "expires_in" in combinazione con Varnish? Potrei filtrare l'intestazione Cache-Control in un'istanza Nginx o Apache di fronte a Varnish, ma ciò sembra strano.

Qualcuno può illuminarmi?

saluti Felix

+0

Sto incontrando lo stesso problema. Hai già trovato una soluzione? – MotoTribe

+0

Vedere il mio commento qui sotto. – GeorgieF

risposta

12

che in realtà è una buona e valida domanda, e uno molto comune con i proxy inverso.

Il problema è che esiste una sola proprietà Cache-Control ed è destinata al browser client (cache privata) e/o a un server proxy (cache condivisa). Se non si desidera che i proxy di terze parti memorizzino il contenuto nel proprio contenuto e desiderino che ogni richiesta venga fornita da Varnish (o dal proprio back-end Rails), è necessario inviare l'intestazione Cache-Control appropriata da Varnish.

Modifica Cache-Control intestazione inviata dal backend è discusso in dettaglio in https://www.varnish-cache.org/trac/wiki/VCLExampleLongerCaching

È possibile avvicinarsi alla soluzione da due angolazioni diverse. Se si desidera definire il max-age nel back-end Rails, ad esempio per specificare TTL diversi per oggetti diversi, è possibile utilizzare il metodo descritto nel link sopra.

Un'altra soluzione è quella di non inviare le intestazioni di Cache-Control dal backend e definire invece i TTL desiderati per gli oggetti in vcl_fetch(). Questo è l'approccio che abbiamo adottato.

Abbiamo un TTL predefinito di 600 secondi in Varnish e definiamo TTL più lunghi per le pagine che sono definitivamente eliminate in modo esplicito quando vengono apportate modifiche. Ecco la nostra vcl_fetch corrente() Definizione:

sub vcl_fetch { 
    if (req.http.Host ~ "(forum|discus)") { 
    # Forum pages are purged explicitly, so cache them for 48h 
    set beresp.ttl = 48h; 
    } 

    if (req.url ~ "^/software/") { 
    # Software pages are purged explicitly, so cache them for 48h 
    set beresp.ttl = 48h; 
    } 

    if (req.url ~ "^/search/forum_search_results") { 
    # We don't want forum search results to be cached for longer than 5 minutes 
    set beresp.ttl = 300s; 
    } 

    if(req.url == "/robots.txt") { 
    # Robots.txt is updated rarely and should be cached for 4 days 
    # Purge manually as required 
    set beresp.ttl = 96h; 
    } 

    if(beresp.status == 404) { 
    # Cache 404 responses for 15 seconds 
    set beresp.http.Cache-Control = "max-age=15"; 
    set beresp.ttl = 15s; 
    set beresp.grace = 15s; 
    } 
} 

Nel nostro caso non inviamo le intestazioni Cache-Control a tutti dai server web di backend.

+3

grazie per la risposta dettagliata. Abbiamo risolto il problema semplicemente cambiando l'intestazione Cache-Control in: Cache-Control: max-age = 0 s-maxage = 86400, public = true quindi il Browser non memorizza nella cache la risorsa ma cache condivise come Varnish do. È sbagliato? – GeorgieF

+4

Puoi anche usare s-maxage. Tuttavia, se gli utenti siedono dietro un proxy trasparente (alcuni ISP continuano a utilizzarli), vedranno la versione memorizzata nella cache anche per un massimo di 24 ore. Se lo si desidera, è possibile utilizzare s-maxage. In caso contrario, dovresti beresp.unset l'intestazione di controllo della cache dalla risposta nel tuo VCL. Modifica la mia risposta per menzionare anche s-maxage. – Ketola

+0

Thx per le tue informazioni in merito. Rifonderemo sicuramente questo e cambieremo in base alla tua soluzione. – GeorgieF

Problemi correlati