You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Varnish缓存忽略特定查询参数?指定请求场景实例

如何让Varnish忽略动态查询参数生成缓存键?

我完全懂你的困扰——那个自动生成的_参数每次请求都不一样,直接导致Varnish每次都生成新的缓存键,根本没法复用之前的缓存,这完全违背了缓存的初衷。别担心,我们可以通过调整Varnish的VCL配置来解决这个问题。

先给你说清楚为什么之前的req.url ~ "^/swatches/(.*)$"配置没用:这个规则只是告诉Varnish“要缓存这个路径下的请求”,但它并没有改变Varnish生成缓存键的逻辑。Varnish默认是用**完整的请求URL(包括所有查询参数)**来生成缓存UID的,所以只要_参数的值变了,缓存键就跟着变,自然命中不了旧缓存。

下面给你两种实用的解决方案,你可以根据自己的需求选:

方案一:修改请求URL,移除动态参数

这种方法会直接修改req.url,把那个烦人的_参数去掉,这样Varnish生成缓存键的时候就只会用到你需要的参数了,同时后端收到的请求也会去掉这个参数。

在你的VCL文件的vcl_recv阶段添加这段代码:

sub vcl_recv {
    # 匹配/swatches/ajax/media/开头的请求URL
    if (req.url ~ "^/swatches/ajax/media/\?") {
        # 移除所有格式为&_=xxx或_=xxx的参数
        set req.url = regsuball(req.url, "&?_=[^&]*", "");
        # 处理替换后可能出现的?&格式问题(比如_是第一个参数的情况)
        set req.url = regsub(req.url, "\?&", "?");
        # 如果最后只剩一个?,直接去掉它
        set req.url = regsub(req.url, "\?$", "");
    }
}

如果你的/swatches/路径下所有请求都需要忽略这个_参数,只要把匹配规则改成req.url ~ "^/swatches/"就行。

方案二:自定义缓存键,排除动态参数

如果你不想修改后端收到的请求URL,只是想让Varnish生成缓存键的时候忽略_参数,可以在vcl_hash阶段自定义缓存键的生成逻辑:

sub vcl_hash {
    # 用处理后的URL(移除_参数)代替默认的req.url
    hash_data(regsuball(req.url, "&?_=[^&]*", ""));
    # 保留主机头作为缓存键的一部分(多域名场景下必须加)
    hash_data(req.http.host);
    # 如果你的场景需要其他缓存维度(比如特定Cookie),可以在这里添加hash_data()
}

这个方法的好处是,后端依然会收到完整的请求URL(包括_参数),但Varnish的缓存键只基于去掉_参数后的URL生成,完美兼顾了缓存和后端需求。

两种方法都能解决你的问题,选哪个看你具体的业务场景就好。

内容的提问来源于stack exchange,提问作者Tanel Tammik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:01:08