2013-01-25 196 views
1

我有一個位於光油後面的Plone網站。除了一件事外,所有的工作都可以。清漆:POST數據後清除緩存

這是一個動態網站,因此會不時有新的內容。場景如下:

我有一個顯示項目列表的頁面。此頁面已被緩存。因此,我通過某種形式添加了另一個項目,並返回到同一頁面,但未顯示新項目。這是因爲顯示的頁面來自緩存並且仍在TTL內。

如何確保在提交新項目時,該頁面將從緩存中清除,並且將顯示來自後端服務器的具有新項目的新頁面?

我簡單的VCL被如圖所示:

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

sub vcl_recv { 
    if (req.request != "GET" && req.request != "HEAD") { 
     # We only deal with GET and HEAD by default 
     return (pass); 
    } 

    # remove unnecessary cookies 
    if (req.http.cookie ~ "wc.cookiecredentials|Path|Domain") { 
     # found wc.cookiecredentials in request, passing to backend server 
     return (lookup); 
    } else { 
     unset req.http.cookie; 
    } 
} 

sub vcl_fetch { 
    #unset beresp.http.Set-Cookie; 
    set beresp.ttl = 12h; 
    return(deliver); 
} 

# Routine used to determine the cache key if storing/retrieving a cached page. 
sub vcl_hash { 
    # Do NOT use this unless you want to store per-user caches. 
    if (req.http.Cookie) { 
     set req.hash += req.http.Cookie; 
    } 
} 

sub vcl_deliver { 
    # send some handy statistics back, useful for checking cache 
    if (obj.hits > 0) { 
     set resp.http.X-Cache-Action = "HIT"; 
     set resp.http.X-Cache-Hits = obj.hits; 
    } else { 
     set resp.http.X-Cache-Action = "MISS"; 
    } 
} 

還是把它說白了,我怎麼能清除或清除整個緩存域每當我收到一個POST請求?

回答

3

要完成此操作,您需要自定義Varnish VCL以處理PURGE請求和您的Plone CMS,以便在內容更改時向清漆發出清除請求。

Plone Developer Documentation在using Varnish with Plone上有非常好的和全面的文檔。您可以根據自己的具體需求進行調整。

本文檔中的示例介紹瞭如何在VCL中創建自定義ACL和正則表達式清除處理,以及如何在Plone中使用該清除來清除整個高速緩存。我從這裏的例子複製的VCL和Plone觀點,以防萬一,他們得到來自Plone站點在未來一段時間內刪除:

acl purge { 
     "localhost"; 
     # XXX: Add your local computer public IP here if you 
     # want to test the code against the production server 
     # from the development instance 
} 

... 

sub vcl_recv { 

     ... 

     # Allow PURGE requests clearing everything 
     if (req.request == "PURGE") { 
       if (!client.ip ~ purge) { 
         error 405 "Not allowed."; 
       } 
       # Purge for the current host using reg-ex from X-Purge-Regex header 
       purge("req.http.host == " req.http.host " && req.url ~ " req.http.X-Purge-Regex); 
       error 200 "Purged."; 
     } 
} 

然後爲Plone創建自定義視圖發放PURGE請求光油:

import requests 

from Products.CMFCore.interfaces import ISiteRoot 
from five import grok 

from requests.models import Request 

class Purge(grok.CodeView): 
    """ 
    Purge upstream cache from all entries. 

    This is ideal to hook up for admins e.g. through portal_actions menu. 

    You can access it as admin:: 

     http://site.com/@@purge 

    """ 

    grok.context(ISiteRoot) 

    # Onlyl site admins can use this 
    grok.require("cmf.ManagePortal") 

    def render(self): 
     """ 
     Call the parent cache using Requets Python library and issue PURGE command for all URLs. 

     Pipe through the response as is. 
     """ 

     # This is the root URL which will be purged 
     # - you might want to have different value here if 
     # your site has different URLs for manage and themed versions 
     site_url = self.context.portal_url() + "/" 

     headers = { 
        # Match all pages 
        "X-Purge-Regex" : ".*" 
     } 

     resp = requests.request("PURGE", site_url + "*", headers=headers) 

     self.request.response["Content-type"] = "text/plain" 
     text = [] 

     text.append("HTTP " + str(resp.status_code)) 

     # Dump response headers as is to the Plone user, 
     # so he/she can diagnose the problem 
     for key, value in resp.headers.items(): 
      text.append(str(key) + ": " + str(value)) 

     # Add payload message from the server (if any) 

     if hasattr(resp, "body"): 
       text.append(str(resp.body)) 

如上所述,這只是簡單地按需清除整個緩存。我不是Plone的專家,所以我無法給你一個詳細的答案,就如何調整它來清除特定的內容。基本上,您需要確定在特定情況下需要清除哪些頁面,然後修改上述示例,以便在Plone中處理POST請求時自動向Varnish發出PURGE請求。

單獨處理VCL中的清除(即檢測POST調用和基於這些清除內容)非常複雜。我相信它將更有效地處理Plone中的邏輯和清除。

更新:

如果你要清除每POST整個緩存,這可以完成如下。

sub vcl_recv { 
    if (req.request == "POST") { 
     ban("req.http.host == " + req.http.Host); 
     return(pass); 
    } 
} 

現在每POST請求導致從緩存中清除已在同一主機名下緩存所有頁面。儘管如此,我仍然建議從長遠來看早期的解決方案。當發生POST時,僅清除實際需要清除的頁面會更有效。

+0

感謝您的回答@Ketola。每當我收到POST請求時,是否有辦法清除整個緩存? – Frankline

+0

確實有。我已經更新了我的答案,以涵蓋此替代方案。雖然這不是一個非常有效的解決方案,並且在這種情況下,緩存命中率永遠不會很高。 – Ketola

+0

這應該是我現在的目的。 – Frankline