基于Node.js(Astro框架)的Nginx与Varnish反向代理架构优化及静态资源缓存配置咨询
首先得说,你把架构调整成Nginx 80 -> Varnish 8080 -> Node.js 3000这个决策非常合理,完全解决了之前的痛点,咱们来拆解下原因:
一、新架构的合理性
之前Varnish在最前面时,既要处理缓存又要应付URL重写、静态资源分发,反而把Nginx的优势浪费了——Nginx天生擅长静态资源高效分发、URL规则处理、错误页托管,把它放在入口层,正好让Varnish专注做它最擅长的动态请求缓存,分工明确。而且之前的Vary头重复问题,现在静态资源直接由Nginx返回,根本不会经过Varnish,从根源上避免了这个问题,一举两得。
二、静态资源一年缓存的配置验证与优化
你现在的Nginx配置其实已经满足静态资源一年缓存的需求了,不过咱们再把细节捋清楚,确保万无一失:
现有配置的优势
你在Nginx里针对静态后缀设置的:
add_header Cache-Control "public, max-age=31536000, immutable"; add_header X-Static-File "true"; expires max;
这完全符合一年缓存的要求——max-age=31536000就是一年,immutable告诉浏览器这个资源不会变,不用再发验证请求,能大幅降低重复请求。
关键注意事项
- 依赖Astro的哈希文件名
Astro默认构建会给静态资源加上哈希后缀(比如main.abc123.js),更新资源时文件名会自动变化,这样即使缓存一年,用户也能拿到最新资源。如果你的Astro配置没开启这个,一定要打开,这是长缓存的核心前提,不然更新资源后用户还会看到旧内容。 - 动态路由不会被干扰
你的Nginx里location /的逻辑是:
这个逻辑会先找对应的静态文件,找不到才转发给Varnish处理动态请求(比如try_files $uri $uri/index.html $uri.html @proxy;/blog/123这类动态路由),完美分离了静态和动态的请求路径,根本不会互相干扰,这个设计很到位。 - 静态资源直接返回,不走Varnish
当前配置里,匹配到静态后缀的请求会直接由Nginx返回,不会进入Varnish,完全符合你新架构的分工,Varnish只处理动态请求,效率更高。
三、Varnish配置的精简建议
看了你的VCL配置,里面还保留了处理静态文件的逻辑(比如vcl_recv里的静态后缀匹配),但现在静态请求根本不会到Varnish了,这些逻辑可以删掉,减少Varnish的不必要判断:
- 删除
vcl_recv中关于静态文件匹配的代码块:if (req.url ~ "^[^?]*\.(7z|avi|bmp|bz2|css|csv|doc|docx|eot|flac|flv|gif|gz|ico|jpeg|jpg|js|less|mka|mkv|mov|mp3|mp4|mpeg|mpg|odt|ogg|ogm|opus|otf|pdf|png|ppt|pptx|rar|rtf|svg|svgz|swf|tar|tbz|tgz|ttf|txt|txz|wav|webm|webp|woff|woff2|xls|xlsx|xml|xz|zip)(\?.*)?$") { set req.http.X-Static-File = "true"; unset req.http.Cookie; return (hash); } - 同时删除
vcl_backend_response中对应的静态文件处理代码:if (bereq.http.X-Static-File == "true" && beresp.http.Cache-Control == "public, max-age=0") { unset beresp.http.Set-Cookie; set beresp.http.X-Static-File = "true"; set beresp.ttl = 1y; }
这样Varnish就能专注处理动态请求,性能会更优。另外,你现在的Vary头处理逻辑是合理的,动态请求的Vary头会合并X-Forwarded-Proto和Accept-Encoding,不会出现重复问题。
四、最后验证要点
调整完后可以做几个测试确保一切正常:
- 访问静态资源(比如
/css/main.css):查看响应头,应该有Cache-Control: public, max-age=31536000, immutable,且没有Varnish的X-Cache头(因为没走Varnish) - 访问动态路由(比如
/api/posts):第一次访问会看到X-Cache: MISS,刷新后变成X-Cache: HIT,说明缓存生效 - 测试URL重写:访问
/about/会重定向到/about,访问/about.html会重定向到/about,确认Nginx的重写逻辑正常 - 测试404页:访问不存在的路径,会返回你自定义的
404.html,且这个页面不会被公开访问(因为internal配置)
整体来看,你的架构和配置已经很完善了,调整后应该能解决之前的问题,同时获得更好的性能。
备注:内容来源于stack exchange,提问作者Predaytor

