2

私は Varnish の背後にある Plone ウェブサイトを持っています。1つのことを除いて、すべて正常に機能しています。

これは動的なサイトであるため、新しいコンテンツが随時追加されます。シナリオは次のとおりです。

アイテムのリストを表示するページがあります。このページはキャッシュされています。そのため、何らかのフォームを介して別のアイテムを追加し、同じページに戻りましたが、新しいアイテムは表示されません。これは、表示されたページがキャッシュからのものであり、まだ 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 要求を受信するたびにドメインのキャッシュ全体をパージまたはクリアするにはどうすればよいですか?

4

1 に答える 1

5

これを達成するには、Varnish VCL をカスタマイズしてPURGEリクエストを処理し、Plone CMS をカスタマイズして、コンテンツが変更されたときに Varnish にパージ リクエストを発行するようにする必要があります。

Plone Developer Documentation には、Plone での Varnish の使用に関する非常に優れた完全なドキュメントがあります。特定のニーズに合わせて調整できます。

ドキュメントの例では、VCL でカスタム ACL と regexp パージ処理を作成する方法と、それを 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.";
        }
}

次に、PlonePURGEに対して、Varnish にリクエストを発行するためのカスタム ビューを作成します。

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 で処理されるPURGEときに自動的に Varnish にリクエストを発行する必要があります。POST

VCL だけでパージを処理する (つまり、POST 呼び出しを検出し、それに基づいてコンテンツをパージする) のは非常に複雑です。Ploneでロジックを処理してパージする方がはるかに効率的だと思います。

アップデート:

ごとにキャッシュ全体を消去する場合はPOST、次のように実行できます。

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

これで、すべてのPOSTリクエストにより、同じホスト名でキャッシュされたすべてのページがキャッシュから削除されます。ただし、長期的には以前のソリューションを検討することをお勧めします。が発生したときに実際にパージする必要があるページのみをパージする方がはるかに効率的POSTです。

于 2013-01-28T14:56:43.133 に答える