启动 Varnish 高性能 HTTP 缓存服务器的核心指令和核心配置

1、启动命令:

/usr/local/varnish/sbin/varnishd \
  -P /var/run/varnish.pid \          # PID文件路径
  -a :8730 \                         # HTTP服务监听端口
  -f /usr/local/varnish/etc/varnish/vcl.conf \  # VCL配置文件
  -T 127.0.0.1:6082 \                # 管理接口地址+端口
  -t 864000 \                        # 会话超时时间
  -w 2,2000,60 \                     # 线程池水位控制
  -u www \                           # 运行用户
  -g www \                           # 运行组
  -s file,/data/varnish/cache/varnish_cache.data,8G \  # 缓存存储配置
  -p thread_pools=1 \                # 线程池数量
  -p thread_pool_min=50 \            # 线程池最小线程数
  -p thread_pool_max=10240 \         # 线程池最大线程数
  -p thread_pool_timeout=10 \        # 线程空闲超时时间
  -p lru_interval=10 \               # LRU缓存清理间隔
  -p listen_depth=1024               # 监听队列深度

参数 / 部分核心作用详细说明 / 调优建议

/usr/local/varnish/sbin/varnishdVarnish 主程序路径采用绝对路径避免环境变量问题,需确保该文件存在且有执行权限

-P /var/run/varnish.pid进程 ID 文件路径记录 varnishd 的 PID,方便后续启停 / 监控(如 kill $(cat /var/run/varnish.pid) 停止服务);需确保 /var/run/ 目录可写

-a :8730客户端访问的监听地址 + 端口:8730 表示监听所有网卡的 8730 端口(HTTP 缓存服务端口);若需指定网卡,可写 192.168.1.10:8730

-f /usr/local/varnish/etc/varnish/vcl.confVCL 配置文件路径VCL(Varnish Configuration Language)是 Varnish 的核心配置文件,定义缓存规则、后端服务器、缓存策略等;启动前需确保该文件语法正确(可通过 varnishd -C -f 文件名 验证)

-T 127.0.0.1:6082管理接口地址 + 端口仅允许本地(127.0.0.1)通过 6082 端口管理 Varnish(如 varnishadm -T 127.0.0.1:6082),禁止外网访问,保证安全

-t 864000会话超时时间(秒)客户端连接的最大空闲时间,864000 秒 = 10 天;建议根据业务调整(如短连接场景设 3600 秒),避免无效连接占用资源

-w 2,2000,60线程池水位控制(min,max,timeout)<ul><li>min=2:线程池最小空闲线程数;</li><li>max=2000:线程池最大空闲线程数;</li><li>timeout=60:空闲线程超过 max 时,60 秒后销毁多余线程;</li><li>调优:高并发场景可提高 max(如 4000),timeout 设 30 秒加快回收。</li></ul>

-u www运行 varnishd 的用户避免以 root 运行,降低安全风险;需提前创建 www 用户(useradd -r -s /sbin/nologin www

-g www运行 varnishd 的用户组与 -u 配合,确保 www 组存在,且对缓存目录有读写权限

-s file,/data/varnish/cache/varnish_cache.data,8G缓存存储配置<ul><li>file:缓存类型为文件存储(适合大容量缓存,另一种是 malloc 内存存储,读写性能极高,无磁盘IO,适合存储热点静态资源);</li><li>/data/varnish/cache/varnish_cache.data:缓存数据文件路径;</li><li>8G:缓存最大容量 8GB;</li><li>注意:需提前创建 /data/varnish/cache/ 目录,且 www 用户有读写权限;内存充足时可改用 malloc,8G(性能更高)。</li></ul>

-p thread_pools=1线程池数量每个线程池对应一个 CPU 核心,建议设为 CPU 逻辑核心数(如 8 核设为 8);单线程池适合低核心服务器,多线程池可提升并发处理能力

-p thread_pool_min=50每个线程池的最小线程数即使无请求,也保留 50 个空闲线程,避免请求突增时创建线程的开销;建议设为并发量的 10%(如预期 500 并发设 50)

-p thread_pool_max=10240每个线程池的最大线程数线程池可创建的最大线程数,10240 适合超高并发场景;需注意:线程数过多会导致 CPU 上下文切换开销增大,建议不超过 20000

-p thread_pool_timeout=10线程空闲超时时间(秒)空闲线程 10 秒无任务则销毁,释放资源;建议设 5~10 秒,平衡资源占用和线程创建开销

-p lru_interval=10LRU 缓存清理间隔(秒)每 10 秒检查一次缓存,淘汰 “最近最少使用(LRU)” 的缓存项,释放空间;建议设 5~30 秒,频繁清理会增加 CPU 负载,间隔太长会导致缓存命中率下降

-p listen_depth=1024监听队列深度内核允许的最大待处理连接数,1024 可应对高并发;若出现 listen queue overflow 错误,需提高该值(如 2048),同时调整内核参数 net.core.somaxconn

2、内核参数调优,提高网络性能:

echo "net.core.somaxconn = 2048" >> /etc/sysctl.conf

echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.conf

sysctl -p

3、核心配置文件vcl.conf:

backend front_thebizark {
.host = "127.0.0.1";
.port = "8800";
.connect_timeout = 60s;
}
backend front_newstar {
.host = "127.0.0.1";
.port = "8900";
.connect_timeout = 60s;
}
acl purge {
     "127.0.0.1";
     "localhost";
 }
sub vcl_recv {
     if (req.restarts == 0) {
        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;
        }
     }
    if (!req.http.cookie) {
        unset req.http.Cookie;
    }
     if (req.request == "BAN") {
     if (req.request == "PURGE") {
        if (!client.ip ~ purge) {
        error 405 "Action is not allowed.";
       }
       ban("req.http.host == " + req.http.host +
       "&& req.url == " + req.url);
       error 200 "Ban added";
       return (lookup);
     }
}    
     if (req.request == "TRACK" ||
         req.request == "TRACE") {
       error 405 "Action is not allowed.";
     }
    if (req.http.Accept-Encoding) {
    if (req.url ~ "\.(gz|tgz|bz2|tbz|tgz|swf|flv|ogg)$") {
        remove 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 {
        remove req.http.Accept-Encoding;
    }
    }  
    if (req.url ~ "\.(jpg|jpeg|png|bmp|gif)$") {
        unset req.http.Cookie;
     }
     if (req.http.host ~ "^.*\.thebizark\.com$" ||
         req.http.host ~ "^thebizark\.com$") {
        set req.backend = front_thebizark;
     }
     if (req.http.host ~ "^.*\.newstar-store\.com$" ||
         req.http.host ~ "^newstar-store\.com$") {
        set req.backend = front_newstar;
     }
     if (req.request != "GET" &&
       req.request != "HEAD" &&
       req.request != "PUT" &&
       req.request != "POST" &&
       req.request != "TRACE" &&
       req.request != "OPTIONS" &&
       req.request != "DELETE") {
         return (pipe);
     }
     if (req.request != "GET" && req.request != "HEAD") {
         return (pass);
     }
     if (req.http.Authorization || req.http.Cookie) {
         return (pass);
     }
     return (lookup);
 }
 
 sub vcl_pipe {
     return (pipe);
 }
 sub vcl_pass {
     return (pass);
 }
 sub vcl_hash {
     hash_data(req.url);
     if (req.http.host) {
         hash_data(req.http.host);
     } else {
         hash_data(server.ip);
     }
     if (req.http.Accept-Encoding) {
     hash_data(req.http.Accept-Encoding);
     }
     return (hash);
 }
 sub vcl_hit {
     if (req.request == "PURGE") {
     set obj.ttl = 0s;
     error 200 "Cache purged.";
     }
     return (deliver);
 }
 sub vcl_miss {
     if (req.request == "PURGE") {
     error 404 "Not in cache.";
     }
     return (fetch);
 }
 sub vcl_fetch {
     if (beresp.ttl <= 0s ||
         beresp.http.Set-Cookie ||
         beresp.http.Vary == "*") {
                set beresp.ttl = 120 s;
                return (hit_for_pass);
     }
     if (beresp.http.content-type ~ "(text|image)") {
              set beresp.do_gzip = true;
     }
     if (req.url ~ "\.(jpg|jpeg|png|bmp|gif)$") {
         unset beresp.http.Set-Cookie;
         set beresp.ttl = 30d;
        }
     return (deliver);
 }
 sub vcl_deliver {
        if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT from Cache";
        } else {
        set resp.http.x-Cache = "MISS from Cache";
        }
     return (deliver);
 }
 sub vcl_error {
     set obj.http.Content-Type = "text/html; charset=utf-8";
     set obj.http.Retry-After = "5";
     synthetic {"
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html>
   <head>
     <title>"} + obj.status + " " + obj.response + {"</title>
   </head>
   <body>
     <h1>Error "} + obj.status + " " + obj.response + {"</h1>
     <p>"} + obj.response + {"</p>
     <h3>Guru Meditation:</h3>
     <p>XID: "} + req.xid + {"</p>
     <hr>
     <p>Varnish cache server</p>
   </body>
 </html>
 "};
     return (deliver);
 }
 sub vcl_init {
        return (ok);
 }
 sub vcl_fini {
        return (ok);
 }

4、启动前准备:

# 1. 创建必要目录

mkdir -p /data/varnish/cache /var/run/varnish

# 2. 设置权限

chown -R www:www /data/varnish /var/run/varnish

# 3. 验证 VCL 配置文件语法

/usr/local/varnish/sbin/varnishd -C -f /usr/local/varnish/etc/varnish/vcl.conf

# 无报错则语法正确,有报错需先修复

Categories: 系统运维