Opencart 3.0.3.8 上的 .html URL 绕过 Varnish 缓存:如何修复缓存配置?

问题描述 投票:0回答:1

我在运行 AlmaLinux 8 并安装了 Plesk 的服务器上有一个 Opencart 3.0.3.8 站点。服务器使用 PHP-FPM 和 Nginx。

我的网站大约有 7,000 个产品,使用完整的 SEO 包模块进行 SEO。单一产品页面和信息页面都有一个 .html 扩展名(这是一个非常古老的设置的遗留物,这个电子商务网站已有大约 15 年的历史)。 Varnish 对于格式为 https://www.example.com/single-product-page 的页面没有问题,但是当我在 https://www.example.com/single-product-page 上查看页面时.html,我看到 x-cache-status 绕过。我已经尝试了一切,但无法解决这个问题。有专家可以告诉我哪里可能出错吗?

标头输出如下:

content-encoding: gzip
content-type: text/html; charset=utf-8
date: Tue, 31 Dec 2024 13:26:58 GMT
permissions-policy: keyboard-map=(), attribution-reporting=(), run-ad-auction=(), private-state-token-redemption=(), private-state-token-issuance=(), join-ad-interest-group=(), idle-detection=(), compute-pressure=(), browsing-topics=()
server: nginx
vary: Accept-Encoding
x-cache-status: BYPASS
x-dns-prefetch-control: off
x-powered-by: PHP/7.3.33
x-powered-by: PleskLin

在 Plesk 面板中,为 http 定义了以下附加指令:

#PLESK-VARNISH-BEGIN
SetEnvIf X-Forwarded-Proto https HTTPS=on
Header set Vary "Accept-Encoding" env=!NO_VARY

<IfModule mod_rewrite.c>
    RewriteEngine on
    # We remove HTTPS redirection because we are behind Varnish
    # RewriteCond %{HTTPS} !=on
    # RewriteCond %{HTTP:X-Forwarded-Proto} !https [NC]
    # RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
#PLESK-VARNISH-END

附加 nginx 指令部分定义如下:

#PLESK-VARNISH-BEGIN
location ~ ^/.* {
    proxy_pass http://0.0.0.0:6081;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Port $server_port;

    # Edit cookie and cache headers
    proxy_hide_header Set-Cookie;
    proxy_ignore_headers Set-Cookie;
    proxy_set_header Cookie "";

    # Timeout settings
    proxy_connect_timeout 300;
    proxy_send_timeout 300;
    proxy_read_timeout 300;
}
#PLESK-VARNISH-END

这是default.vcl文件的内容:

#########################################################################
###               The perfect Varnish 4.x+ configuration              ###
### for WordPress, Joomla, Drupal & other (common) CMS based websites ###
#########################################################################

######################
#
# UPDATED on December 15th, 2021
#
# Configuration Notes:
# 1. Default dynamic content caching respects your backend's cache-control HTTP header.
#    If however you need to enforce a different cache-control TTL,
#    do a search for "180" and replace with the new value in seconds.
#    Stale cache is served for up to 24 hours.
# 2. Make sure you update the "backend default { ... }" section with the correct IP and port
#
######################

# Varnish Reference:
# See the VCL chapters in the User-Guide at https://varnish-cache.org/docs/

# Marker to tell the VCL compiler that this VCL has been adapted to the new 4.1 format
vcl 4.1;

# Imports
import std;

# ACL defination
acl purge {
    "localhost";
    "127.0.0.1";
}

# Default backend definition. Set this to point to your content server.
backend default {
    .host = "127.0.0.1";
    .port = "7080";
}

sub vcl_recv {
    std.log("Client IP: " + client.ip);
    std.log("Request URL: " + req.url);
    std.log("Request method: " + req.method);

    # Cookie handling
    if (req.http.Cookie) {
        set req.http.Cookie = regsuball(req.http.Cookie, "^(OCSESSID=.*?;?).*$", "\1");
        set req.http.Cookie = regsuball(req.http.Cookie, "^(language=.*?;?).*$", "\1");
        set req.http.Cookie = regsuball(req.http.Cookie, "^(currency=.*?;?).*$", "\1");
        if (req.http.Cookie ~ "^\s*$") {
            unset req.http.Cookie;
        }
    }

    # Basic request handling
    if (req.http.Set-Cookie) { return(pass); }
    
    # Purge handling
    if (req.method == "PURGE") {
        if (!client.ip ~ purge) {
            return(synth(405, "Not allowed."));
        }
        if (req.http.X-Purge-Method == "regex") {
            ban("req.url ~ " + req.http.X-Purge-Regex);
        } else {
            ban("req.url == " + req.url);
        }
        return(synth(200, "Cache cleared"));
    }

    # LetsEncrypt passthrough
    if (req.url ~ "^/\.well-known/acme-challenge/") {
        return (pass);
    }

    # Forward client IP
    if (req.restarts == 0) {
        if (req.http.X-Real-IP) {
            set req.http.X-Forwarded-For = req.http.X-Real-IP;
        } else 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;
        }
    }

    # Security
    unset req.http.proxy;
    
    # URL normalization
    if (req.url !~ "wp-admin") {
        set req.url = std.querysort(req.url);
    }

    # Method handling
    if (req.method != "GET" && req.method != "HEAD" && 
        req.method != "PUT" && req.method != "POST" && 
        req.method != "TRACE" && req.method != "OPTIONS" && 
        req.method != "DELETE") {
        return (pipe);
    }

    if (req.method != "GET" && req.method != "HEAD") {
        return (pass);
    }

    # URL cleanup
    if (req.url ~ "(\?|&)(_bta_[a-z]+|fbclid|gclid|utm_[a-z]+)=") {
        set req.url = regsuball(req.url, "(_bta_[a-z]+|fbclid|gclid|utm_[a-z]+)=[-_A-z0-9+()%.]+&?", "");
        set req.url = regsub(req.url, "[?|&]+$", "");
    }

    if (req.url ~ "\?$") { set req.url = regsub(req.url, "\?$", ""); }
    if (req.url ~ "\#") { set req.url = regsub(req.url, "\#.*$", ""); }

    # Cookie cleanup
    std.collect(req.http.Cookie);
    set req.http.Cookie = regsuball(req.http.Cookie, "(has_js|_ga|wp-settings-[0-9]+|wordpress_test_cookie)=[^;]+(; )?", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "^;\s*", "");
    if (req.http.cookie ~ "^\s*$") { unset req.http.cookie; }

    # Cache bypass conditions
    if (req.http.Authorization || 
        req.http.Authenticate || 
        req.http.X-Logged-In == "True" || 
        req.http.Cookie ~ "(userID|joomla_[a-zA-Z0-9_]+|wordpress_[a-zA-Z0-9_]+|wp-postpass)") {
        return (pass);
    }

    # Path exclusions
    if (req.url ~ "^/(administrator|cart|checkout|login|wp-admin|wp-login.php)") {
        return (pass);
    }

    # AJAX handling
    if (req.http.X-Requested-With == "XMLHttpRequest" || req.url ~ "nocache") {
        return (pass);
    }

    # Static file handling
    if (req.http.Accept-Encoding) {
        if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
            unset req.http.Accept-Encoding;
        } elsif (req.http.Accept-Encoding ~ "gzip") {
            set req.http.Accept-Encoding = "gzip";
        } elsif (req.http.Accept-Encoding ~ "deflate") {
            set req.http.Accept-Encoding = "deflate";
        } else {
            unset req.http.Accept-Encoding;
        }
    }

    # Static content bypass
    if (req.url ~ "\.(css|js|jpg|jpeg|png|gif|ico|woff|ttf|eot|svg)$") {
        unset req.http.Cookie;
        return (hash);
    }

    return (hash);
}

sub vcl_backend_response {
    # Static file optimization
    if (bereq.url ~ "\.(jpg|jpeg|gif|png|css|js|ico|woff|ttf|eot|svg)$") {
        unset beresp.http.Set-Cookie;
        set beresp.ttl = 30d;
        set beresp.http.Cache-Control = "public, max-age=2592000";
    }

    # Error handling
    if (beresp.status >= 500 && beresp.status <= 504) {
        return (abandon);
    }

    # Cache control
    if (beresp.http.Cache-Control !~ "max-age" || beresp.http.Cache-Control ~ "max-age=0") {
        set beresp.http.Cache-Control = "public, max-age=180, stale-while-revalidate=360, stale-if-error=43200";
    }

    # Header cleanup
    unset beresp.http.Pragma;
    unset beresp.http.Vary;
    
    set beresp.grace = 24h;
    
    return (deliver);
}

sub vcl_deliver {
    # Cache status headers
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT";
        set resp.http.X-Cache-Hits = obj.hits;
        std.log("Cache HIT for: " + req.url);
    } else {
        set resp.http.X-Cache = "MISS";
        std.log("Cache MISS for: " + req.url);
    }
    
    return (deliver);
}
php varnish plesk
1个回答
0
投票

日志可能会公开有关页面未缓存原因的更多信息。

假设我们正在调试假设的

/single-product-page.html
产品页面,日志记录命令如下:

sudo varnishlog -g request -q "ReqUrl eq '/single-product-page.html'"

请将此

varnishlog
命令的完整输出粘贴到您的原始问题中。输出可以包含多个相关交易(请求交易和后端请求交易)。

我将帮助您分析输出并弄清楚发生了什么。请确保在

varnishlog
运行时触发该页面。另请调整过滤模式,以确保
/single-product-page.html
替换为实际产品页面。

© www.soinside.com 2019 - 2024. All rights reserved.