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

如何用Varnish缓存内容并实现无缓存HTTPS反向代理?

使用Varnish实现游戏文件缓存+无缓存HTTPS反向代理方案

架构说明

Varnish原生不处理HTTPS请求,因此需要前置SSL终止层(这里用你熟悉的Nginx),整体流程:
客户端HTTPS请求 → Nginx(SSL终止) → Varnish(缓存/路由) → 目标后端服务器


1. Nginx SSL终止配置

先配置Nginx监听443端口,完成SSL解密后转发请求到Varnish(示例端口8080),确保传递正确的Host头:

server {
    listen 443 ssl;
    server_name game-update.example.com no-cache.example.com;

    # SSL证书配置(替换为你的证书路径)
    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    # 转发请求到Varnish
    location / {
        proxy_pass http://127.0.0.1:8080;
        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;
    }
}

2. Varnish核心VCL配置

编辑/etc/varnish/default.vcl,区分缓存/无缓存请求,配置后端路由和缓存策略:

定义后端服务器

# 游戏更新文件后端(缓存目标)
backend game_update {
    .host = "game-update-backend.example.com";
    .port = "80";
    # 如果后端是HTTPS,添加以下配置:
    # .ssl = true;
    # .ssl_verify_hostname = false; # 自签名证书需开启,信任证书则设为true
}

# 无缓存服务后端
backend no_cache_service {
    .host = "no-cache-backend.example.com";
    .port = "80";
}

请求处理逻辑(vcl_recv)

sub vcl_recv {
    # 标记HTTPS请求来源
    if (req.http.X-Forwarded-Proto) {
        set req.http.X-Forwarded-Proto = "https";
    }

    # 规则1:缓存游戏更新/文件类请求
    if (req.host == "game-update.example.com" || req.url ~ "^/update/|\.(zip|exe|pak|bin)$") {
        # 仅缓存GET/HEAD请求
        if (req.method != "GET" && req.method != "HEAD") {
            return (pass);
        }
        # 清除Cookie避免缓存碎片化(游戏更新通常无需Cookie)
        unset req.http.Cookie;
        # 自定义缓存键,确保不同域名的资源独立缓存
        set req.hash_data = req.host;
        set req.hash_data = req.url;
        # 强制设置缓存有效期(1天,按需调整)
        set req.http.Cache-Control = "public, max-age=86400";
        return (hash);
    }

    # 规则2:无缓存反向代理请求
    if (req.host == "no-cache.example.com") {
        set req.backend_hint = no_cache_service;
        return (pass); # 直接转发到后端,不经过缓存
    }

    # 默认规则:其他请求直接转发
    return (pass);
}

响应处理逻辑(vcl_backend_response)

sub vcl_backend_response {
    # 游戏更新资源:强制缓存并清除后端Set-Cookie
    if (bereq.host == "game-update.example.com" || bereq.url ~ "^/update/|\.(zip|exe|pak|bin)$") {
        unset beresp.http.Set-Cookie;
        set beresp.ttl = 86400s;
        set beresp.http.Cache-Control = "public, max-age=86400";
        set beresp.http.X-Cached-By = "Varnish";
        return (deliver);
    }

    # 无缓存资源:禁用缓存
    if (bereq.host == "no-cache.example.com") {
        set beresp.ttl = 0s;
        set beresp.http.Cache-Control = "no-cache, no-store, must-revalidate";
        return (deliver);
    }
}

3. dnsmasq域名解析配置

将需要代理的域名指向Nginx服务器IP,编辑/etc/dnsmasq.conf添加:

# 游戏更新域名解析到Nginx IP
address=/game-update.example.com/192.168.1.100
# 无缓存服务域名解析到Nginx IP
address=/no-cache.example.com/192.168.1.100

重启dnsmasq生效:

systemctl restart dnsmasq

排查Host头代理失败问题

  1. Nginx必须传递Host头:确保proxy_set_header Host $host;存在,否则Varnish拿到的Host是127.0.0.1:8080,无法匹配后端规则。
  2. 检查Varnish日志:用varnishlog -g request查看请求流程,确认Host头是否正确传递,规则是否匹配。
  3. 后端HTTPS适配:如果后端是HTTPS,必须在Varnish backend配置中开启.ssl = true,并根据证书情况设置.ssl_verify_hostname。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 00:45:44