2013-07-16 27 views
5

Artık ne yaptığımı bilmiyorum. Nerede başlayacağımı bilmediğim pek çok sorun vardı. Bunun yerine Varnish bir ters proxy olarak kullanıldı app.php dosyasında Symfony'nin AppCache devre dışı bıraktıkSymfony ESI, çerezler etkinse, vernik önbelleğini etkinleştirir

varnishd (varnish-3.0.3 revision 9e6a70f) 
Server version: Apache/2.2.22 (Unix) 
Symfony 2.3.1 

İlk: İşte benim yapılandırma. Çünkü

Varnish (80) <--> Apache (8080)

# /etc/varnish/default.vcl 
backend default { 
    .host = "127.0.0.1"; 
    .port = "8080"; 
} 

sub vcl_recv { 
    if (req.http.Cache-Control ~ "no-cache") { 
     return (pass); 
    } 

    if (!(req.url ~ "^/dashboard/")) { 
     unset req.http.Cookie; 
    } 

    # Remove has_js and Google Analytics __* cookies. 
    set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", ""); 
    # Remove a ";" prefix, if present. 
    set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", ""); 

    #set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js)=[^;]*", ""); 
    set req.http.Surrogate-Capability = "abc=ESI/1.0"; 

    if (req.restarts == 0) { 
     if (req.http.x-forwarded-for) { 
      set req.http.X-Forwarded-For = 
      req.http.X-Forwarded-For + ", " + client.ip; 
     } else { 
      set req.http.X-Forwarded-For = client.ip; 
     } 
    } 

    if (req.request != "GET" && 
     req.request != "HEAD" && 
     req.request != "PUT" && 
     req.request != "POST" && 
     req.request != "TRACE" && 
     req.request != "OPTIONS" && 
     req.request != "DELETE") { 
     /* Non-RFC2616 or CONNECT which is weird. */ 
     return (pipe); 
    } 

f (req.request != "GET" && req.request != "HEAD") { 
     /* We only deal with GET and HEAD by default */ 
     return (pass); 
    } 

    if (req.http.Authorization) { 
     /* Not cacheable by default */ 
     return (pass); 
    } 

    return (lookup); 
} 

sub vcl_pipe { 
    return (pipe); 
} 

sub vcl_pass { 
    return (pass); 
} 

sub vcl_hash { 
    hash_data(req.url); 

    if (req.http.host) { 
     hash_data(req.http.host); 
    } else { 
     hash_data(server.ip); 
    } 

    return (hash); 
} 

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

    # Varnish determined the object was not cacheable 
    if (beresp.ttl <= 0s) { 
     set beresp.http.X-Varnish-Cacheable = "NO:Not Cacheable"; 

    # You don't wish to cache content for logged in users 
    } elsif (req.http.Cookie ~ "(UserID|_session)") { 
     set beresp.http.X-Varnish-Cacheable = "NO:Got Session"; 
     return(hit_for_pass); 

    # You are respecting the Cache-Control=private header from the backend 
    } elsif (beresp.http.Cache-Control ~ "private") { 
     set beresp.http.X-Varnish-Cacheable = "NO:Cache-Control=private"; 
     return(hit_for_pass); 

    # Varnish determined the object was cacheable 
    } else { 
     set beresp.http.X-Varnish-Cacheable = "YES"; 
    } 

    if (beresp.status >= 300) { 
     return (hit_for_pass); 
    } 

    if (beresp.http.Pragma ~ "no-cache" || 
     beresp.http.Cache-Control ~ "no-cache" || 
     beresp.http.Cache-Control ~ "private") { 
     return (hit_for_pass); 
    } 

    return (deliver); 
} 

sub vcl_hit { 
    return (deliver); 
} 

sub vcl_deliver { 
    if (obj.hits > 0) { 
     set resp.http.X-Varnish-Cached = "HIT"; 
    } else { 
     set resp.http.X-Varnish-Cached = "MISS"; 
    } 
    return (deliver); 
} 

sub vcl_error { 
    set obj.http.Content-Type = "text/html; charset=utf-8"; 
    set obj.http.Retry-After = "5"; 

    synthetic {" 
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html> 
    <head> 
    <title>"} + obj.status + " " + obj.response + {"</title> 
    </head> 
    <body> 
    <h1>Error "} + obj.status + " " + obj.response + {"</h1> 
    <p>"} + obj.response + {"</p> 
    <h3>Guru Meditation:</h3> 
    <p>XID: "} + req.xid + {"</p> 
    <hr> 
    <p>Varnish cache server</p> 
    </body> 
</html> 
"}; 

    return (deliver); 
} 

sub vcl_init { 
    return (ok); 
} 

sub vcl_fini { 
    return (ok); 
} 

: Burada

benim Vernik yapılandırması

if (!(req.url ~ "^/dashboard/")) { 
    unset req.http.Cookie; 
} 

Vernik kamu sayfaların tümünü Çerezler kaldırır ve iyi Cache, vurur ama ... Vernik, giriş yapamayacağım tüm çerezleri sildiğinden beri (oturum çerezi oturum yok demektir).

Oturum açma düğmesini, önbellek başlığına sahip bir ESI bloğunda var ancak bu hala düzeltmiyor. İşte önyüzü denetleyicisi geçerli:

public function indexAction() 
{ 
    $response = $this->render('AcmeCoreBundle:Default:index.html.twig'); 
    $response->setSharedMaxAge(21600); // 6 hours 
    return $response; 
} 

şablon uzanır layout.html.twig:

<html lang="en-US"> 
<head> 
    ... 
</head> 
<body> 
    ... 

    <div class="top-right"> 
     {{ render_esi(controller('AcmeUserBundle:Default:loginBox')) }} 
    </div> 

    ... 
</body> 

ve AcmeUserBundle:Default:loginBox kontrolör:

public function loginBoxAction() 
{ 
    $response = $this->render('AcmeUserBundle:Block:home_login.html.twig'); 
    $response->setVary('Cookies', false); 
    $response->setMaxAge(0); 
    $response->setPrivate(); 

    return $response; 
} 

Ben Oturum çerezleri nasıl yönetileceğini bilmiyorum Symfony için. Her sayfada bir facebook bağlantı düğmesine sahip olduğum için kullanıcı oturumuna sahip olmam gerekiyor. Ve Symfony anonim kullanıcı için bile bir çerez oluşturduğundan, tüm isteklerde oturum çerezleri var.

Yardım büyük takdir :)

sayesinde Maxime'i


GÜNCELLEME: Yeni VCL dosyaları önerileri sonra:

... 

sub vcl_recv { 

    if (!(req.url ~ "^/dashboard") && !(req.url ~ "^/logout") && !(req.url ~ "^/_fragment") && req.esi_level == 0) { 
     set req.http.Esi-Cookie = req.http.Cookie; 
     unset req.http.Cookie; 
    } 

    if (!(req.url ~ "^/dashboard") && req.esi_level > 0) { 
     set req.http.Cookie = req.http.Esi-Cookie; 
    } 

    # Remove has_js and Google Analytics __* cookies. 
    set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", ""); 

    # Remove a ";" prefix, if present. 
    set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", ""); 

    # Force ESI capability header 
    set req.http.Surrogate-Capability = "abc=ESI/1.0"; 

    if (req.restarts == 0) { 
     if (req.http.x-forwarded-for) { 
      set req.http.X-Forwarded-For = 
      req.http.X-Forwarded-For + ", " + client.ip; 
     } else { 
      set req.http.X-Forwarded-For = client.ip; 
     } 
    } 

    if (req.request != "GET" && 
     req.request != "HEAD" && 
     req.request != "PUT" && 
     req.request != "POST" && 
     req.request != "TRACE" && 
     req.request != "OPTIONS" && 
     req.request != "DELETE") { 
     /* Non-RFC2616 or CONNECT which is weird. */ 
     return (pipe); 
    } 

    # if Authorization or no-cache header we skip the cache 
    if (req.http.Authorization || req.http.Cache-Control ~ "no-cache") { 
     return (pass); 
    } 

    # If not GET or HEAD request we skip the cache 
    if (req.request != "GET" && req.request != "HEAD") { 
     return (pass); 
    } 

    return (lookup); 
} 

... 

sub vcl_fetch { 

    if (!(req.url ~ "^/dashboard") && !(req.url ~ "^/login_check")) { 
     unset beresp.http.set-cookie; 
    } 

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

    # Varnish determined the object was not cacheable 
    if (beresp.ttl <= 0s) { 
     set beresp.http.X-Varnish-Cacheable = "NO:Not Cacheable"; 

    # You don't wish to cache content for logged in users 
    } elsif (req.http.Cookie ~ "(UserID|_session)") { 
     set beresp.http.X-Varnish-Cacheable = "NO:Got Session"; 
     return(hit_for_pass); 

    # You are respecting the Cache-Control=private header from the backend 
    } elsif (beresp.http.Cache-Control ~ "private") { 
     set beresp.http.X-Varnish-Cacheable = "NO:Cache-Control=private"; 
     return(hit_for_pass); 

    # Varnish determined the object was cacheable 
    } else { 
     set beresp.http.X-Varnish-Cacheable = "YES"; 
    } 

    if (beresp.status >= 300) { 
     return (hit_for_pass); 
    } 

    if (beresp.http.Pragma ~ "no-cache" || 
     beresp.http.Cache-Control ~ "no-cache" || 
     beresp.http.Cache-Control ~ "private") { 
     return (hit_for_pass); 
    } 

    return (deliver); 
} 

Her kamu sayfa artık düzgün önbelleğe alınır . Giriş sayfasındaki her yerde HIT'leri önbelleğe aldım ancak şu an için büyük bir anlaşma değil.

Sahip olduğum sorun, üstbilgideki ESI bloğunda. Verniğin, url'yi arayarak <esi:include> numaralı telefonu talep ettiği apache erişim günlüğünde görebiliyorum.

Ana sayfada görüntülenen ESI bloğu doğru değil (kullanıcı giriş yapmamış gibi oturum açma URL'si gösteriyor) ancak doğrudan /_fragment numaralı telefonu ararsam, döndürülen blok doğrudur (kullanıcı bilgileriyle birlikte).

o nereden geldiğini gerçekten bilmiyorum ama ben çok yakınım :)

cevap

5

bir gelen istek çerez alındı ​​başlığını Çıkarma ESI istekleri şunlardır çıkan tüm kaldırır.Bu ana sayfa için istek tarayıcı çerezi şeritler

if (!(req.url ~ "^/dashboard/") && req.esi_level == 0) { 
    set req.http.Esi-Cookie = req.http.Cookie; 
    unset req.http.Cookie; 
} 
if (!(req.url ~ "^/dashboard/") && req.esi_level > 0) { 
    set req.http.Cookie = req.http.Esi-Cookie; 
} 

, bunlarla yeniden ekler: Eğer önbelleğe alınmış olduğu dahildir kaynaklarda çerez başlığına erişimi, ancak ebeveyn, istediğimizden, bu deneyin esi'den kaynaklanan esi talepleri: döndürülmüş sayfada etiketleri ekleyin. Yukarıdaki kodu tweetlemedim, bu yüzden% 100 mükemmel olmayabilir.

if (!(req.url ~ "^/dashboard/") && req.esi_level > 0) { 
    set req.http.Cookie = req.http.Esi-Cookie; 
    return (pass); 
} 
+1

teşekkür arkadaşı: vcl_recv olarak

Güncelleme

, hiç önbelleğe veya yinelemeli esi bir esi parçasını işlemek istemiyorsanız, eğer blok ikinci değiştirebilir. Symfony, anonim kullanıcılar için bile bir oturum çerezi oluşturduğundan, oturum açmış kullanıcılar için ikinci bir çerez oluşturmanın çözüm olabileceğini düşünüyor musunuz? Oturum açılmış çerez varsa, çerezi kaldırmazsa, çerezleri kaldırın. Bu, giriş yapan kullanıcılar için Önbellek MISS ve anonim kullanıcılar için Cache HIT ile sonuçlanacaktır. Ne düşünüyorsun? – maxwell2022

+1

VCL'nizin doğru şekilde ayarlandığından emin olmak için verniğe yapılan isteklerin çerez üstbilgisini inceleyin. Ayrıca, doğrudan/_fragment kaynağına isabet ederken, yanıt üstbilgilerini açıkça iptal edilemediğinden emin olun (veya güncellemede önerdiğim gibi esi istekleri için geri (geçiş)) –