2月 202010
 

以下の記事でもチラッと書いたのですがVarnishの現バージョンではESIのTTL指定がesi:includeタグからできません

VarnishでESIを使うときの注意するべき点

単純に考えるのであればvcl_fetchでそれぞれのURLで指定すればいいとも言えるのですが
ESIの利点を多少損なっている感もします
(個人的にはデザイナ側がこのパーツは10分キャッシュしてもユーザに影響しないよ!とか設定できるのが利点と思ってる)
じゃぁどうすればいいのでしょうか
あまりスマートではないですが解決方法があります

例えばdocument root直下にあるhello.htmlを
ESIでincludeしたい場合で10秒のTTLを指定する時に


<esi:include src="/esi/t/10s/hello.html" />

こんな感じの記述でできるようになります

default.vcl


############################################################
sub vcl_miss {
    set bereq.url=regsub(req.url,"^/esi/t/[0-9]+[smh]?/","/");
    set bereq.http.X-VARNISH-ESI="1";
    fetch;
}
############################################################
sub vcl_pass {
    set bereq.url=regsub(req.url,"^/esi/t/[0-9]+[smh]?/","/");
    set bereq.http.X-VARNISH-ESI="1";
    pass;
}
############################################################
sub vcl_pipe{
    set bereq.url=regsub(req.url,"/esi/t/[0-9]+[smh]?/","/");
    set bereq.http.X-VARNISH-ESI="1";
    pipe;
}
############################################################
sub vcl_recv {
    unset req.http.Accept-Encoding;
    if(req.url ~ "ESIでもキャッシュされるとまずいURL正規表現(広告とか)"){
        pass;
    }elseif(req.http.X-VARNISH-ESI){
        lookup;
    }elseif(req.url ~ "^/esi/t/0[smh]?/"){
        pass;
    }elseif(req.url ~ "親ページがキャッシュされるとまずいURL正規表現(連動広告とか)"){
        pass;
    }else{
        lookup;
    }
}
############################################################
sub vcl_fetch {
    esi;
    set obj.ttl=1m;//デフォルトのTTL値
    //ESI用のinclude
    include "esi.vcl";
}
############################################################

esi.vcl


if (req.url ~ "^/esi/t/") {
    if(req.url ~ "^/esi/t/0/") {
        set obj.ttl=0s;
    }elseif(req.url ~ "^/esi/t/[0-9]+s/") {
        if(req.url ~ "^/esi/t/[0-9]s/") {
            if(req.url ~ "^/esi/t/0")     {set obj.ttl=0s;}
            elseif(req.url ~ "^/esi/t/1")    {set obj.ttl=1s;}
            elseif(req.url ~ "^/esi/t/2")    {set obj.ttl=2s;}
            elseif(req.url ~ "^/esi/t/3")    {set obj.ttl=3s;}
            elseif(req.url ~ "^/esi/t/4")    {set obj.ttl=4s;}
            elseif(req.url ~ "^/esi/t/5")    {set obj.ttl=5s;}
            elseif(req.url ~ "^/esi/t/6")    {set obj.ttl=6s;}
            elseif(req.url ~ "^/esi/t/7")    {set obj.ttl=7s;}
            elseif(req.url ~ "^/esi/t/8")    {set obj.ttl=8s;}
            elseif(req.url ~ "^/esi/t/9")    {set obj.ttl=9s;}
        }
        elseif(req.url ~ "^/esi/t/[0-9][0-9]s/") {
            if(req.url ~ "^/esi/t/1") {
                if(req.url ~ "^/esi/t/[0-9]0")     {set obj.ttl=10s;}
                elseif(req.url ~ "^/esi/t/[0-9]1") {set obj.ttl=11s;}
                elseif(req.url ~ "^/esi/t/[0-9]2") {set obj.ttl=12s;}
                elseif(req.url ~ "^/esi/t/[0-9]3") {set obj.ttl=13s;}
                elseif(req.url ~ "^/esi/t/[0-9]4") {set obj.ttl=14s;}
                elseif(req.url ~ "^/esi/t/[0-9]5") {set obj.ttl=15s;}
                elseif(req.url ~ "^/esi/t/[0-9]6") {set obj.ttl=16s;}
                elseif(req.url ~ "^/esi/t/[0-9]7") {set obj.ttl=17s;}
                elseif(req.url ~ "^/esi/t/[0-9]8") {set obj.ttl=18s;}
                elseif(req.url ~ "^/esi/t/[0-9]9") {set obj.ttl=19s;}
            }elseif(req.url ~ "^/esi/t/2") {
                if(req.url ~ "^/esi/t/[0-9]0")         {set obj.ttl=20s;}
                elseif(req.url ~ "^/esi/t/[0-9]1")     {set obj.ttl=21s;}
                elseif(req.url ~ "^/esi/t/[0-9]2") {set obj.ttl=22s;}
                elseif(req.url ~ "^/esi/t/[0-9]3") {set obj.ttl=23s;}
                elseif(req.url ~ "^/esi/t/[0-9]4") {set obj.ttl=24s;}
                elseif(req.url ~ "^/esi/t/[0-9]5") {set obj.ttl=25s;}
                elseif(req.url ~ "^/esi/t/[0-9]6") {set obj.ttl=26s;}
                elseif(req.url ~ "^/esi/t/[0-9]7") {set obj.ttl=27s;}
                elseif(req.url ~ "^/esi/t/[0-9]8") {set obj.ttl=28s;}
                elseif(req.url ~ "^/esi/t/[0-9]9") {set obj.ttl=29s;}
            }elseif(req.url ~ "^/esi/t/3") {
                if(req.url ~ "^/esi/t/[0-9]0")         {set obj.ttl=30s;}
                elseif(req.url ~ "^/esi/t/[0-9]1")     {set obj.ttl=31s;}
                elseif(req.url ~ "^/esi/t/[0-9]2") {set obj.ttl=32s;}
                elseif(req.url ~ "^/esi/t/[0-9]3") {set obj.ttl=33s;}
                elseif(req.url ~ "^/esi/t/[0-9]4") {set obj.ttl=34s;}
                elseif(req.url ~ "^/esi/t/[0-9]5") {set obj.ttl=35s;}
                elseif(req.url ~ "^/esi/t/[0-9]6") {set obj.ttl=36s;}
                elseif(req.url ~ "^/esi/t/[0-9]7") {set obj.ttl=37s;}
                elseif(req.url ~ "^/esi/t/[0-9]8") {set obj.ttl=38s;}
                elseif(req.url ~ "^/esi/t/[0-9]9") {set obj.ttl=39s;}
            }elseif(req.url ~ "^/esi/t/4") {
                if(req.url ~ "^/esi/t/[0-9]0")         {set obj.ttl=40s;}
                elseif(req.url ~ "^/esi/t/[0-9]1")     {set obj.ttl=41s;}
                elseif(req.url ~ "^/esi/t/[0-9]2") {set obj.ttl=42s;}
                elseif(req.url ~ "^/esi/t/[0-9]3") {set obj.ttl=43s;}
                elseif(req.url ~ "^/esi/t/[0-9]4") {set obj.ttl=44s;}
                elseif(req.url ~ "^/esi/t/[0-9]5") {set obj.ttl=45s;}
                elseif(req.url ~ "^/esi/t/[0-9]6") {set obj.ttl=46s;}
                elseif(req.url ~ "^/esi/t/[0-9]7") {set obj.ttl=47s;}
                elseif(req.url ~ "^/esi/t/[0-9]8") {set obj.ttl=48s;}
                elseif(req.url ~ "^/esi/t/[0-9]9") {set obj.ttl=49s;}
            }elseif(req.url ~ "^/esi/t/5") {
                if(req.url ~ "^/esi/t/[0-9]0")         {set obj.ttl=50s;}
                elseif(req.url ~ "^/esi/t/[0-9]1")     {set obj.ttl=51s;}
                elseif(req.url ~ "^/esi/t/[0-9]2") {set obj.ttl=52s;}
                elseif(req.url ~ "^/esi/t/[0-9]3") {set obj.ttl=53s;}
                elseif(req.url ~ "^/esi/t/[0-9]4") {set obj.ttl=54s;}
                elseif(req.url ~ "^/esi/t/[0-9]5") {set obj.ttl=55s;}
                elseif(req.url ~ "^/esi/t/[0-9]6") {set obj.ttl=56s;}
                elseif(req.url ~ "^/esi/t/[0-9]7") {set obj.ttl=57s;}
                elseif(req.url ~ "^/esi/t/[0-9]8") {set obj.ttl=58s;}
                elseif(req.url ~ "^/esi/t/[0-9]9") {set obj.ttl=59s;}
            }
        }
    }elseif(req.url ~ "^/esi/t/[0-9]+m/") {
        if(req.url ~ "^/esi/t/[0-9]m/") {
            if(req.url ~ "^/esi/t/0")     {set obj.ttl=0m;}
            elseif(req.url ~ "^/esi/t/1")    {set obj.ttl=1m;}
            elseif(req.url ~ "^/esi/t/2")    {set obj.ttl=2m;}
            elseif(req.url ~ "^/esi/t/3")    {set obj.ttl=3m;}
            elseif(req.url ~ "^/esi/t/4")    {set obj.ttl=4m;}
            elseif(req.url ~ "^/esi/t/5")    {set obj.ttl=5m;}
            elseif(req.url ~ "^/esi/t/6")    {set obj.ttl=6m;}
            elseif(req.url ~ "^/esi/t/7")    {set obj.ttl=7m;}
            elseif(req.url ~ "^/esi/t/8")    {set obj.ttl=8m;}
            elseif(req.url ~ "^/esi/t/9")    {set obj.ttl=9m;}
        }
        elseif(req.url ~ "^/esi/t/[0-9][0-9]m/") {
            if(req.url ~ "^/esi/t/1") {
                if(req.url ~ "^/esi/t/[0-9]0")     {set obj.ttl=10m;}
                elseif(req.url ~ "^/esi/t/[0-9]1") {set obj.ttl=11m;}
                elseif(req.url ~ "^/esi/t/[0-9]2") {set obj.ttl=12m;}
                elseif(req.url ~ "^/esi/t/[0-9]3") {set obj.ttl=13m;}
                elseif(req.url ~ "^/esi/t/[0-9]4") {set obj.ttl=14m;}
                elseif(req.url ~ "^/esi/t/[0-9]5") {set obj.ttl=15m;}
                elseif(req.url ~ "^/esi/t/[0-9]6") {set obj.ttl=16m;}
                elseif(req.url ~ "^/esi/t/[0-9]7") {set obj.ttl=17m;}
                elseif(req.url ~ "^/esi/t/[0-9]8") {set obj.ttl=18m;}
                elseif(req.url ~ "^/esi/t/[0-9]9") {set obj.ttl=19m;}
            }elseif(req.url ~ "^/esi/t/2") {
                if(req.url ~ "^/esi/t/[0-9]0")         {set obj.ttl=20m;}
                elseif(req.url ~ "^/esi/t/[0-9]1")     {set obj.ttl=21m;}
                elseif(req.url ~ "^/esi/t/[0-9]2") {set obj.ttl=22m;}
                elseif(req.url ~ "^/esi/t/[0-9]3") {set obj.ttl=23m;}
                elseif(req.url ~ "^/esi/t/[0-9]4") {set obj.ttl=24m;}
                elseif(req.url ~ "^/esi/t/[0-9]5") {set obj.ttl=25m;}
                elseif(req.url ~ "^/esi/t/[0-9]6") {set obj.ttl=26m;}
                elseif(req.url ~ "^/esi/t/[0-9]7") {set obj.ttl=27m;}
                elseif(req.url ~ "^/esi/t/[0-9]8") {set obj.ttl=28m;}
                elseif(req.url ~ "^/esi/t/[0-9]9") {set obj.ttl=29m;}
            }elseif(req.url ~ "^/esi/t/3") {
                if(req.url ~ "^/esi/t/[0-9]0")         {set obj.ttl=30m;}
                elseif(req.url ~ "^/esi/t/[0-9]1")     {set obj.ttl=31m;}
                elseif(req.url ~ "^/esi/t/[0-9]2") {set obj.ttl=32m;}
                elseif(req.url ~ "^/esi/t/[0-9]3") {set obj.ttl=33m;}
                elseif(req.url ~ "^/esi/t/[0-9]4") {set obj.ttl=34m;}
                elseif(req.url ~ "^/esi/t/[0-9]5") {set obj.ttl=35m;}
                elseif(req.url ~ "^/esi/t/[0-9]6") {set obj.ttl=36m;}
                elseif(req.url ~ "^/esi/t/[0-9]7") {set obj.ttl=37m;}
                elseif(req.url ~ "^/esi/t/[0-9]8") {set obj.ttl=38m;}
                elseif(req.url ~ "^/esi/t/[0-9]9") {set obj.ttl=39m;}
            }elseif(req.url ~ "^/esi/t/4") {
                if(req.url ~ "^/esi/t/[0-9]0")         {set obj.ttl=40m;}
                elseif(req.url ~ "^/esi/t/[0-9]1")     {set obj.ttl=41m;}
                elseif(req.url ~ "^/esi/t/[0-9]2") {set obj.ttl=42m;}
                elseif(req.url ~ "^/esi/t/[0-9]3") {set obj.ttl=43m;}
                elseif(req.url ~ "^/esi/t/[0-9]4") {set obj.ttl=44m;}
                elseif(req.url ~ "^/esi/t/[0-9]5") {set obj.ttl=45m;}
                elseif(req.url ~ "^/esi/t/[0-9]6") {set obj.ttl=46m;}
                elseif(req.url ~ "^/esi/t/[0-9]7") {set obj.ttl=47m;}
                elseif(req.url ~ "^/esi/t/[0-9]8") {set obj.ttl=48m;}
                elseif(req.url ~ "^/esi/t/[0-9]9") {set obj.ttl=49m;}
            }elseif(req.url ~ "^/esi/t/5") {
                if(req.url ~ "^/esi/t/[0-9]0")         {set obj.ttl=50m;}
                elseif(req.url ~ "^/esi/t/[0-9]1")     {set obj.ttl=51m;}
                elseif(req.url ~ "^/esi/t/[0-9]2") {set obj.ttl=52m;}
                elseif(req.url ~ "^/esi/t/[0-9]3") {set obj.ttl=53m;}
                elseif(req.url ~ "^/esi/t/[0-9]4") {set obj.ttl=54m;}
                elseif(req.url ~ "^/esi/t/[0-9]5") {set obj.ttl=55m;}
                elseif(req.url ~ "^/esi/t/[0-9]6") {set obj.ttl=56m;}
                elseif(req.url ~ "^/esi/t/[0-9]7") {set obj.ttl=57m;}
                elseif(req.url ~ "^/esi/t/[0-9]8") {set obj.ttl=58m;}
                elseif(req.url ~ "^/esi/t/[0-9]9") {set obj.ttl=59m;}
            }
        }
    }elseif(req.url ~ "^/esi/t/[0-9]+h/") {
        if(req.url ~ "^/esi/t/[0-9]h/") {
            if(req.url ~ "^/esi/t/0")     {set obj.ttl=0h;}
            elseif(req.url ~ "^/esi/t/1")    {set obj.ttl=1h;}
            elseif(req.url ~ "^/esi/t/2")    {set obj.ttl=2h;}
            elseif(req.url ~ "^/esi/t/3")    {set obj.ttl=3h;}
            elseif(req.url ~ "^/esi/t/4")    {set obj.ttl=4h;}
            elseif(req.url ~ "^/esi/t/5")    {set obj.ttl=5h;}
            elseif(req.url ~ "^/esi/t/6")    {set obj.ttl=6h;}
            elseif(req.url ~ "^/esi/t/7")    {set obj.ttl=7h;}
            elseif(req.url ~ "^/esi/t/8")    {set obj.ttl=8h;}
            elseif(req.url ~ "^/esi/t/9")    {set obj.ttl=9h;}
        }
        elseif(req.url ~ "^/esi/t/[0-9][0-9]h/") {
            if(req.url ~ "^/esi/t/1") {
                if(req.url ~ "^/esi/t/[0-9]0")     {set obj.ttl=10h;}
                elseif(req.url ~ "^/esi/t/[0-9]1") {set obj.ttl=11h;}
                elseif(req.url ~ "^/esi/t/[0-9]2") {set obj.ttl=12h;}
                elseif(req.url ~ "^/esi/t/[0-9]3") {set obj.ttl=13h;}
                elseif(req.url ~ "^/esi/t/[0-9]4") {set obj.ttl=14h;}
                elseif(req.url ~ "^/esi/t/[0-9]5") {set obj.ttl=15h;}
                elseif(req.url ~ "^/esi/t/[0-9]6") {set obj.ttl=16h;}
                elseif(req.url ~ "^/esi/t/[0-9]7") {set obj.ttl=17h;}
                elseif(req.url ~ "^/esi/t/[0-9]8") {set obj.ttl=18h;}
                elseif(req.url ~ "^/esi/t/[0-9]9") {set obj.ttl=19h;}
            }elseif(req.url ~ "^/esi/t/2") {
                if(req.url ~ "^/esi/t/[0-9]0")         {set obj.ttl=20h;}
                elseif(req.url ~ "^/esi/t/[0-9]1")     {set obj.ttl=21h;}
                elseif(req.url ~ "^/esi/t/[0-9]2") {set obj.ttl=22h;}
                elseif(req.url ~ "^/esi/t/[0-9]3") {set obj.ttl=23h;}
                elseif(req.url ~ "^/esi/t/[0-9]4") {set obj.ttl=24h;}
                elseif(req.url ~ "^/esi/t/[0-9]5") {set obj.ttl=25h;}
                elseif(req.url ~ "^/esi/t/[0-9]6") {set obj.ttl=26h;}
                elseif(req.url ~ "^/esi/t/[0-9]7") {set obj.ttl=27h;}
                elseif(req.url ~ "^/esi/t/[0-9]8") {set obj.ttl=28h;}
                elseif(req.url ~ "^/esi/t/[0-9]9") {set obj.ttl=29h;}
            }elseif(req.url ~ "^/esi/t/3") {
                if(req.url ~ "^/esi/t/[0-9]0")         {set obj.ttl=30h;}
                elseif(req.url ~ "^/esi/t/[0-9]1")     {set obj.ttl=31h;}
                elseif(req.url ~ "^/esi/t/[0-9]2") {set obj.ttl=32h;}
                elseif(req.url ~ "^/esi/t/[0-9]3") {set obj.ttl=33h;}
                elseif(req.url ~ "^/esi/t/[0-9]4") {set obj.ttl=34h;}
                elseif(req.url ~ "^/esi/t/[0-9]5") {set obj.ttl=35h;}
                elseif(req.url ~ "^/esi/t/[0-9]6") {set obj.ttl=36h;}
                elseif(req.url ~ "^/esi/t/[0-9]7") {set obj.ttl=37h;}
                elseif(req.url ~ "^/esi/t/[0-9]8") {set obj.ttl=38h;}
                elseif(req.url ~ "^/esi/t/[0-9]9") {set obj.ttl=39h;}
            }elseif(req.url ~ "^/esi/t/4") {
                if(req.url ~ "^/esi/t/[0-9]0")         {set obj.ttl=40h;}
                elseif(req.url ~ "^/esi/t/[0-9]1")     {set obj.ttl=41h;}
                elseif(req.url ~ "^/esi/t/[0-9]2") {set obj.ttl=42h;}
                elseif(req.url ~ "^/esi/t/[0-9]3") {set obj.ttl=43h;}
                elseif(req.url ~ "^/esi/t/[0-9]4") {set obj.ttl=44h;}
                elseif(req.url ~ "^/esi/t/[0-9]5") {set obj.ttl=45h;}
                elseif(req.url ~ "^/esi/t/[0-9]6") {set obj.ttl=46h;}
                elseif(req.url ~ "^/esi/t/[0-9]7") {set obj.ttl=47h;}
                elseif(req.url ~ "^/esi/t/[0-9]8") {set obj.ttl=48h;}
                elseif(req.url ~ "^/esi/t/[0-9]9") {set obj.ttl=49h;}
            }elseif(req.url ~ "^/esi/t/5") {
                if(req.url ~ "^/esi/t/[0-9]0")         {set obj.ttl=50h;}
                elseif(req.url ~ "^/esi/t/[0-9]1")     {set obj.ttl=51h;}
                elseif(req.url ~ "^/esi/t/[0-9]2") {set obj.ttl=52h;}
                elseif(req.url ~ "^/esi/t/[0-9]3") {set obj.ttl=53h;}
                elseif(req.url ~ "^/esi/t/[0-9]4") {set obj.ttl=54h;}
                elseif(req.url ~ "^/esi/t/[0-9]5") {set obj.ttl=55h;}
                elseif(req.url ~ "^/esi/t/[0-9]6") {set obj.ttl=56h;}
                elseif(req.url ~ "^/esi/t/[0-9]7") {set obj.ttl=57h;}
                elseif(req.url ~ "^/esi/t/[0-9]8") {set obj.ttl=58h;}
                elseif(req.url ~ "^/esi/t/[0-9]9") {set obj.ttl=59h;}
            }
        }
    }
}

はいすごい強引ですね!
簡単な解説
index.phpの中でこんな記述をする


<esi:include src="/esi/t/10s/index.php?esi=1" />


vcl_recvで解釈してESI処理

vcl_missでX-VARNISH-ESIを付与(←結構ポイント)
してバックエンドに/index.phpを呼び出し

ESI部分(/esi/t/10s/index.php?esi=1)を処理

TTLを
/esi/t/10s/
に基づいて10秒設定

vcl_missでバックエンドリクエストURLから/esi/t/10sを除外
かつX-VARNISH-ESIを付与(←結構ポイント)

ApacheなりNginxで/index.php?esi=1の処理を行う

varnishがくっつけて返す

こんな感じですね
X-VARNISH-ESI(名前はなんでもOK)をつけるのが個人的にポイントだと思っているのですが
これはたとえば何らかの理由でESIをはずさなくてはならないときに簡単に対処できるためです
X-VARNISH-ESIがついてたらESI動作してるってことでそれを前提、ついてなければ通常動作みたいな感じで
また、X-VARNISH-ESIがついていた場合は基本的にキャッシュ動作するということでたとえば
/my.php
がキャッシュしちゃまずいけど中のパーツはキャッシュしたい!みたな動作も制御できます
この場合


    }elseif(req.url ~ "親ページがキャッシュされるとまずいURL正規表現(連動広告とか)"){

にmy.phpってかいとけば初回のバックエンドリクエストの際はキャッシュされないけど
なかに


<esi:include src="/esi/t/10m/my.php?esi=1" />

とか書いて自分を再帰呼び出しする際はキャッシュされるみたいなことも可能です
コレの用途はESIパーツが複数あって複数のキャッシュされてはまずいコンテンツが連動するケース
(広告などで同じの出したくないとかそういうの)
に有効です


    if(req.url ~ "ESIでもキャッシュされるとまずいURL正規表現(広告とか)"){

またここに書いておけば広告など毎回コールが必要なものは必ずcallされます

また当然ですが/esi/t/10s/index.phpと/esi/t/2s/index.phpは別々のTTLで動作しますのでキャッシュまじりは起きません
あと同じファイル名でクエリで分ける必要もないですよ!

ちなみに上記設定では
/esi/t/0/ キャッシュしない
/esi/t/10s/ 10秒キャッシュ
/esi/t/10m/ 10分キャッシュ
/esi/t/10h/ 10時間キャッシュ
といった感じで動作します
指定は0-59まで可能です


 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください