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

Varnish Max Threads触顶及后端、会话连接突增问题排查与优化咨询

问题概述

遇到Varnish Max Threads触顶、后端连接与会话连接突增问题,暂未明确根因,观测到该问题仅在源站响应耗时较高、最终返回不可缓存的502响应时触发。

Varnish部署说明

Varnish部署在Nginx代理后方,入站请求先到达Nginx,再通过一致性负载均衡转发至多台Varnish节点;缓存未命中时,Varnish会请求源站Nginx节点(本例为example.com)。当前场景下仅缓存HTTP GET请求,所有响应均为JSON载荷,大小范围为0.001MB~2MB。

请求示例

HTTP GET请求地址:http://test.com/test/abc?arg1=val1&arg2=val2
预期xkey:test/abc
响应:JSON载荷

运行指标

  • 预估QPS:60~80 HTTP GET请求
  • 平均对象TTL:2d
  • 平均对象grace时长:1d

Varnish及相关配置

版本信息

Varnish版本:varnish-6.5.1,运行于Linux 5.4.0 x86_64环境

启动命令

varnishd -F -j unix,user=nobody -a :6081 -T localhost:6082 -f /etc/varnish/default.vcl -s file,/opt/varnishdata/cache,750G

VCL配置

vcl 4.0;
import xkey;
import std;

acl purgers {
    "localhost";
}

backend default {
    .host = "example.com";
    .port = "80";
}

sub vcl_recv {
    unset req.http.Cookie;
    if (req.method == "PURGE") {
        if (client.ip !~ purgers) {
            return (synth(403, "Forbidden"));
        }
        if (req.http.xkey) {
            set req.http.n-gone = xkey.softpurge(req.http.xkey);
            return (synth(200, "Invalidated "+req.http.n-gone+" objects"));
        }
        else {
           return (purge);
        }
    }
    # 移除请求中的reqid参数
    set req.url = regsuball(req.url, "reqid=[-_A-z0-9+()%.]+&?", "");
    # 移除末尾的?或&符号
    set req.url = regsub(req.url, "[?|&]+$", "");
    # 设置后端请求的host头
    set req.http.host = "example.com";
}

sub vcl_backend_response {
    # 若后端未返回缓存相关头,设置默认TTL
    set beresp.ttl = std.duration(beresp.http.X-Cache-ttl, 2d);
    # 设置stale内容服务的grace时长
    set beresp.grace = std.duration(beresp.http.X-Cache-grace, 1d);
    # 提取xkey
    if (bereq.url ~ "/some-string/") {
        set beresp.http.xkey = regsub (bereq.url,".*/some-string/([^?]+).*","\1");
    }

    # 该逻辑保证若上游返回5xx,只要缓存中存在对应响应(即使已过期),就返回缓存内容(直到grace时长耗尽)
    if ( beresp.status != 200 &&  beresp.status != 422 ){
        # 该判断十分重要:若is_bgfetch为true,说明已向客户端返回缓存对象,且触发了异步后台更新。此时若后端返回5xx,需要放弃更新,否则即使设置uncacheable为true,原有缓存对象也会被清除
        if (bereq.is_bgfetch)
        {
            return (abandon);
        }

        # 禁止缓存5xx响应
        set beresp.uncacheable = true;
    }
}

sub vcl_deliver {
    unset resp.http.X-Varnish;
    unset resp.http.Via;
    set resp.http.X-Cached = req.http.X-Cached;
}
sub vcl_hit {
    if (obj.ttl >= 0s) {
       set req.http.X-Cached = "HIT";
       return (deliver);
    }
    if (obj.ttl + obj.grace > 0s) {
        set req.http.X-Cached = "STALE";
        return (deliver);
    }
    set req.http.X-Cached = "MISS";
}
sub vcl_miss {
    set req.http.X-Cached = "MISS";
}

优化建议

根因初步判断

故障触发逻辑符合源站降级场景下的缓存雪崩特征:源站响应变慢+返回不可缓存502时,缓存无法命中,所有请求直接透传至源站,每个请求占用Varnish线程的时间被大幅拉长,线程池快速耗尽,进而引发会话、后端连接突增的连锁反应。

配置优化点

1. VCL逻辑优化

  • 补全异步刷新逻辑:当前配置仅实现了grace期返回过期内容,未触发后台异步刷新,缓存过期后首个请求必须同步等待源站响应,故障场景下会加剧线程占用。需要在vcl_recv中添加set req.grace = 1d;,同时在vcl_hit的STALE分支后添加return (restart);触发后台异步回源,避免用户请求同步等待源站。
  • 增加请求合并逻辑:开启Varnish默认的请求合并(request coalescing)功能,避免同一个缓存Key的大量请求同时回源,故障场景下可减少90%以上的无效回源量,可在vcl_recv中显式配置set req.hash_always_miss = false;避免逻辑被覆盖。
  • 新增5xx错误短缓存规则:当前5xx响应完全不缓存,故障场景下会导致所有请求持续打源站。可在设置beresp.uncacheable = true;的同时添加set beresp.ttl = 5s;,短时间内复用错误响应,避免源站压力进一步恶化。
  • 修复xkey提取逻辑:当前xkey仅匹配/some-string/路径,和示例中的/test/abc路径不匹配,软清理功能完全失效,需要调整正则匹配规则覆盖所有业务路径。
  • 补充请求方法过滤:明确仅缓存GET请求,在vcl_recv中添加非GET请求直接透传的逻辑,避免非预期请求占用缓存资源。

2. 启动参数优化

  • 调整线程池配置:当前启动命令未配置线程参数,默认线程上限较低,容易被打满。可添加参数-p thread_pool_min=50 -p thread_pool_max=1000 -p thread_pool_timeout=120,根据实际业务规模调整上限,预留足够的线程缓冲空间。
  • 新增源站超时配置:避免请求长时间挂在源站响应上占用线程,添加参数-p connect_timeout=5s -p first_byte_timeout=30s -p between_bytes_timeout=10s,超过阈值直接终止请求返回错误或降级内容。

3. 降级策略优化

可新增源站异常降级逻辑,当源站5xx占比超过阈值时,直接返回兜底数据,无需持续等待源站响应。


需补充的排查信息
  1. 故障时刻的varnishstat输出,重点关注MAIN.thread_limited(线程受限次数)、MAIN.backend_fail(后端失败次数)、MAIN.cache_miss(缓存未命中数)、MAIN.queued_requests(排队请求数)核心指标
  2. 正常运行期和故障期的缓存命中率对比数据
  3. 故障时刻的varnishlog采样,确认请求处理链路的耗时分布
  4. 源站故障时刻的响应耗时、502错误占比数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 21:06:03