3

ワニス 4 で猶予時間を設定する場所について混乱しています。VCL がvcl_recvで猶予時間を設定する例を見てきました。

sub vcl_recv {
    ...
    set req.http.grace = 60m;
    ...
}

他の人はvcl_hitで設定します

sub vcl_hit {
    ...
    set obj.grace = 60m;
    ...
}

ドキュメント(https://www.varnish-cache.org/docs/4.0/users-guide/vcl-grace.html)では、vcl_backend_responseに設定されています

sub vcl_backend_response {
    ...
    set beresp.grace = 60m;
    ...
}

vcl_recvvcl_backend_responseの両方で猶予時間が設定されている例も見ました。

特定の場所に設定したい理由を誰か説明してもらえますか?

実際には、バックエンドが正常であると見なされるかどうかに応じて、猶予時間を設定したいと考えています。直感的に、ワニスがバックエンドに接続する前に設定するので、 vcl_recvで猶予時間を設定し、次のようにvcl_hitでキャッシュからサーバーするかどうかを決定します。

sub vcl_recv {
    ...
    if (std.healthy(req.backend_hint)) {
        set req.http.grace = 2m;
    } else {
        set req.http.grace = 60m;
    }
    ...
}

sub vcl_hit {
    if (obj.ttl >= 0s) {
        # A standard hit, deliver from cache
        return (deliver);
    }
    elsif (obj.ttl + obj.grace > 0s) {
        # page expired, serve from cache in the meantime
        return (deliver);
    } else {
        return (fetch);
    }
}

これは正しいアプローチですか?

4

1 に答える 1

4

これは私の研究ソファの結果です:

  1. vcl_recvreq.http.graceを設定しても、新しいヘッダー エントリを定義するだけなので役に立ちませんが、そうしないと varnish はそれを無視します。
  2. vcl_hitobj.graceを設定しても、varnish 4 では obj が読み取り専用であるため機能しません。
  3. varnish がそれを認識できるように猶予時間を設定できる唯一の場所は、beresp.grace のサブルーチンvcl_backend_responseあります。
  4. 猶予時間はvcl_backend_responseでのみ設定できるため、バックエンドの状態に応じて異なる猶予時間を設定することはできません。この関数は、キャッシュ ミス後に varnish がバックエンドからデータをフェッチするときにのみ呼び出されるため、必要なものには遅すぎます。バックエンドに接続する前に猶予時間を設定する必要があります。

バックエンドの状態に応じて異なる猶予時間を設定するための私の解決策は次のとおりです。

  1. 猶予時間を「通常の猶予時間」と「バックエンドが異常な場合の猶予時間」の 2 つの猶予時間の最大値に設定しています。
  2. キャッシュから提供するか、バックエンドに接続するかはvcl_hitで決定されます。ここで 2 回目の猶予時間をエミュレートできます

これが私のvcl_hitがどのように見えるかです

sub vcl_hit {
        if (obj.ttl >= 0s) {
                # A standard hit, deliver from cache
                return (deliver);
        }
        elsif (std.healthy(req.backend_hint)) {
                if (obj.ttl + 30m > 0s) {
                        # page expired within a limited grace time and backend
                        # is healthy: deliver from cache while cache is updated
                        # asynchronous
                        return (deliver);
                } else {
                        # page expired too long ago - fetch from backend
                        return (fetch);
                }
        }
        else {
                if (obj.ttl + obj.grace > 0s) {
                        # backend is not healthy - provide the page from cache
                        # during full grace time set in vcl_backend_response
                        return (deliver);
                } else {
                        # page expired for the full grace time and backend is
                        # considered unhealthy - try to contact the backend
                        # anyway
                        return (fetch);
                }
        }
}

ここでは、条件を使用して 30 分の 2 番目の猶予時間を「定義」しました。

            if (obj.ttl + 30m > 0s) {

vcl_backend_responseで、最大猶予時間を 6 時間に設定しました

sub vcl_backend_response {
        # define full grace time here
        set beresp.grace = 6h;
        ...
}
于 2015-10-07T16:59:22.797 に答える