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

为Drupal配置Varnish查询参数白名单,大幅提升性能

为Drupal配置Varnish查询参数白名单解决服务器负载异常实践

去年年底,来自中国和新加坡的爬虫激增导致服务器瘫痪,排查后发现大量请求存在冗余、错位、重复或损坏的查询参数,具体表现如下:

  • 新闻页出现无关参数:/news?page=1&site=domain.org&type=page
  • 重复参数请求:/list?page=1&page=15&page=120
  • 损坏格式参数:/news?;page=1

这类问题直接导致Varnish无法正常缓存,缓存池中充斥大量重复内容,进而引发服务器负载异常。

解决方案:Varnish查询参数白名单配置

通过在Varnish的vcl_recv子程序中配置查询参数白名单,使用自定义临时头X-Query存储允许保留的参数,针对JS资源、图片样式及特定页面的查询参数做过滤处理,具体代码如下:

sub vcl_recv {
    ...
    # Remove unnecessary query strings to improve caching.
    # Check if URL has query string
    if (req.url ~ "\?") {
        # JS
        if (req.url ~ "\.js\?v=") {
            set req.http.X-Query = "";
            if (req.url ~ "\?v=") {
                set req.http.X-Query = req.http.X-Query + regsub(req.url, "^.+\?(v=[^&]+).*?$", "&\1");
            }
            set req.url = regsub(req.url, "\?.+", regsub(req.http.X-Query, "^&", "?"));
            unset req.http.X-Query;
        }
        # Image styles
        elseif (req.url ~ "(\?|&)itok=" && req.url ~ "\.(webp|jpg|png)") {
            set req.http.X-Query = "";
            if (req.url ~ "(\?|&)itok=") {
                set req.http.X-Query = req.http.X-Query + regsub(req.url, "^.+?(\?|&)(itok=[^&]+).*?$", "&\2");
            }
            set req.url = regsub(req.url, "\?.+", regsub(req.http.X-Query, "^&", "?"));
            unset req.http.X-Query;
        }
        # Some page with multiple query params
        elseif (req.url ~ "/some-page" && req.url ~ "(\?|&)(group|t1|t2|t3|t4n|a)") {
            set req.http.X-Query = "";
            if (req.url ~ "(\?|&)group=") {
                set req.http.X-Query = req.http.X-Query + regsub(req.url, "^.+?(\?|&)(group=[^&]+).*?$", "&\2");
            }
            if (req.url ~ "(\?|&)t1=") {
                set req.http.X-Query = req.http.X-Query + regsub(req.url, "^.+?(\?|&)(t1=[^&]+).*?$", "&\2");
            }
            if (req.url ~ "(\?|&)t2=") {
                set req.http.X-Query = req.http.X-Query + regsub(req.url, "^.+?(\?|&)(t2=[^&]+).*?$", "&\2");
            }
            if (req.url ~ "(\?|&)t3=") {
                set req.http.X-Query = req.http.X-Query + regsub(req.url, "^.+?(\?|&)(t3=[^&]+).*?$", "&\2");
            }
            if (req.url ~ "(\?|&)t4n=") {
                set req.http.X-Query = req.http.X-Query + regsub(req.url, "^.+?(\?|&)(t4n=[^&]+).*?$", "&\2");
            }
            if (req.url ~ "(\?|&)a=") {
                set req.http.X-Query = req.http.X-Query + regsub(req.url, "^.+?(\?|&)(a=[^&]+).*?$", "&\2");
            }
            set req.url = regsub(req.url, "\?.+", regsub(req.http.X-Query, "^&", "?"));
            unset req.http.X-Query;
        }
    ...
}

实施效果

方案部署后服务器负载迅速恢复正常,同时带来额外收益:

  • Varnish内存占用显著降低
  • 缓存命中率大幅提升
  • URL格式更规范统一
  • 减少恶意参数请求,增强站点安全性

优化建议征集

目前的实现中存在较多重复代码,诚邀各位提供优化思路,比如是否可以通过抽取子例程的方式减少代码冗余?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 10:05:08