首页 > 其他分享 >【Varnish】:解决 Varnish 7.6 CDN 静态资源缓存失效问题

【Varnish】:解决 Varnish 7.6 CDN 静态资源缓存失效问题

时间:2025-01-14 23:57:05浏览次数:3  
标签:Varnish 缓存 http CDN Cache Via 7.6

项目场景:

在一个使用Varnish作为反向代理的Web应用中,我们依赖CDN(内容分发网络)来缓存静态资源(如图片、CSS、JavaScript文件等),以提高全球用户的访问速度并减轻源站服务器的负载。然而,在实际运行中,我们遇到了一个问题:CDN缓存的静态资源全部一直回源,导致源站服务器负载过高,响应时间延长,用户体验下降。

问题描述:

症状表现

  • 高源站流量: 监控数据显示源站接收到大量本应由CDN处理的请求。
  • 低缓存命中率: CDN平台中显示静态资源的缓存命中率远低于预期。
  • 响应时间延长: 用户体验到比预期更长的页面加载时间。
  • Via 头部异常: 在响应头中发现了额外的 Via 信息,例如 1.1 yjcm-varnish-0 (Varnish/7.6), cache14.l2et135-6[2,0],这可能是导致CDN失效的原因之一。

产生影响

这些症状直接影响了用户体验和网站性能,增加了服务器负载,当时LB带宽几乎要达到上限。随着系统响应时间逐渐变慢,用户体验急剧下降。因此,解决这个问题对于提升网站的整体性能至关重要。

原因分析:

经过详细的日志分析和技术排查,我们确定以下因素可能导致了上述问题:

1. Via 头部的影响:

  • 标准的 Via 响应头用于标识请求经过的代理服务器链。如果Varnish保留或添加了这个头部,某些CDN可能会误判请求路径,进而影响缓存决策。
  • 特别是当 Via 头部包含多个代理服务器的信息时,可能会使CDN认为每个请求都是唯一的,从而阻止了缓存的有效利用。

2. 自定义VCL逻辑:

  • 如果Varnish配置中有特定的逻辑来决定何时缓存内容或如何处理请求,这些逻辑可能会与CDN的预期行为相冲突,导致缓存策略不再适用。

3. Cookie处理:

  • 默认情况下,如果请求包含 Cookie 头部,Varnish通常不会缓存该请求。这可能导致静态资源因为会话信息而被视为独特的,从而绕过了缓存。

4. 缓存控制头部不一致:

  • Varnish可能修改了来自后端服务器或CDN的关键HTTP头部信息(如 Cache-Control, Expires),导致CDN认为这些资源不应该被缓存。

5. 系统性能瓶颈:

  • 随着系统响应时间变慢,可能存在其他性能瓶颈,如数据库查询效率低下、应用程序代码中的阻塞操作、服务器资源不足等。这些问题会进一步加剧响应时间的延迟。

解决方案:

为了解决这些问题,我们采取了一系列措施,确保Varnish与CDN之间顺畅协作,最大化缓存效率并提升整体网站性能。同时,我们也针对系统性能进行了优化,以改善响应时间。

1. 修改 vcl_deliver 子程序

通过调整 vcl_deliver 子程序,可以实现更清晰的缓存状态指示,并避免不必要的头部冲突:

# 交付子程序 (vcl_deliver)
sub vcl_deliver {
    # 显示缓存命中/未命中信息
    # 这个逻辑用于在响应头中添加一个自定义的头部 X-Varnish-Cache,
    # 以便后续可以通过这个头部判断请求是否被缓存命中。
    if (obj.hits > 0) {
        set resp.http.X-Varnish-Cache = "hit";  # 如果缓存命中(即该对象已被缓存并再次访问),则设置 X-Varnish-Cache 为 hit
    } else {
        set resp.http.X-Varnish-Cache = "miss";  # 如果缓存未命中(即该对象是第一次访问或缓存已过期),则设置 X-Varnish-Cache 为 miss
    }

    # 将 Via 头的内容复制到 X-Varnish-Via 头
    # Via 是一个标准的HTTP头部,用来标识请求经过的代理服务器链。
    # 为了避免影响CDN对缓存决策的理解,我们将原始的 Via 头内容复制到一个新的头部 X-Varnish-Via,
    # 并删除原来的 Via 头,确保CDN不会因为额外的代理信息而误判请求路径。
    if (resp.http.Via) {
        set resp.http.X-Varnish-Via = resp.http.Via;  # 将原始 Via 头内容复制到新的 X-Varnish-Via 头
        unset resp.http.Via;  # 删除原来的 Via 头,避免干扰CDN的缓存决策
    }
}

解释:

  • 显示缓存状态: 通过添加 X-Varnish-Cache 响应头,提供了关于缓存命中的明确指示,这对于调试和理解缓存行为非常有用。
  • 清理 Via 头: Via 头通常用于标识请求经过的代理服务器链。将其内容复制到 X-Varnish-Via 并删除原始 Via 头,可以帮助减少混淆,并确保CDN能够正确解析响应。

2. 同步缓存控制头部

确保Varnish不会覆盖或修改来自后端服务器或CDN的关键缓存控制头部,如 Cache-Control 和 Expires。可以通过以下方式同步这些头部:

sub vcl_backend_response {
    # 同步 Cache-Control 和 Expires 头部
    if (beresp.http.Cache-Control && beresp.http.Expires) {
        set beresp.http.Cache-Control = beresp.http.Cache-Control;
        set beresp.http.Expires = beresp.http.Expires;
    }
}

3. 确保缓存一致性

确保Varnish和CDN之间的缓存策略一致,特别是对于静态资源的缓存控制头部:

  • 标准化响应头部: 保持所有响应头部的一致性,有助于维持整个系统的稳定性和性能。
  • 检查缓存标签: 确认Varnish和CDN都支持并正确处理缓存标签(如 ETag, Last-Modified)。

4. 测试与验证

  • 测试清除效果: 在非生产环境中进行更改前,先在一个小范围内测试,确保不会对用户体验产生负面影响。
  • 监控性能变化: 使用性能监控工具来跟踪实施更改后的性能指标,确保问题得到解决且没有引入新的问题。

结论

通过精心调整Varnish配置并遵循最佳实践,我们可以确保Varnish与CDN之间顺畅协作,最大化缓存效率并提升整体网站性能。希望这篇文章能为你和其他开发者提供有价值的参考,帮助解决类似的缓存失效问题。如果有更多复杂的需求或疑问,建议参考官方文档或寻求专业支持。

标签:Varnish,缓存,http,CDN,Cache,Via,7.6
From: https://blog.csdn.net/qq_34272964/article/details/145149423

相关文章

  • Linux(Centos 7.6)命令详解:split
    1.命令作用Linux系统中的一个用于拆分文件的命令。它可以将一个大文件拆分成多个小文件,以便于传输、存储或处理2.命令语法Usage:split[OPTION]...[INPUT[PREFIX]]Usage:split[选项]... [输入文件][输出文件前缀]3.参数详解OPTION:-a,--suffix-length=N,生成分裂......
  • Linux(Centos 7.6)命令详解:tree
    1.命令作用以树状格式列出目录的内容(listcontentsofdirectoriesinatree-likeformat);tree会递归显示子层目录下所有内容,但默认情况下不包括隐藏文件和目录2.命令语法Usage:tree[OPTION]... [<directorylist>]3.参数详解OPTION:-a,all显示所有文件和目录(包......
  • 7.6 2D卷积
    OpenCV的自定义卷积函数在OpenCV中,允许用户自定义卷积核实现卷积操作,使用自定义卷积核实现卷积操作的函数是cv2.filter2D(),其语法格式为:dst=cv2.filter2D(src,ddepth,kernel,anchor,delta,borderType)式中:dst是返回值,表示进行方框滤波后得到的处理......
  • 优化博客Ⅱ-CDN加速
    CDN加速自从有了第一次博客优化经验,我就越发对优化感兴趣了嘿嘿(✧∇✧)。看着博客首页打开时长为1200ms左右,我又开始琢磨有什么办法能再给网站提提速,让访问时间降低到1000ms以下,这时候我想起前不久群里讨论过这个问题,我翻回去看见他们提到了CDN加速。CDN加速?好耳熟(ㅇㅅ......
  • Linux(Centos 7.6)命令详解:mkdir
    1.命令作用如果目录还不存在,则创建目录(CreatetheDIRECTORY,iftheydonotalreadyexist.)2.命令语法Usage:mkdir[OPTION]...DIRECTORY...3.参数详解OPTION:-m,--mode=MODE,创建新目录同时设置权限模式-p,--parents,创建多层目录,如上层目录不存在会自动创建-v,-......
  • 解决 Spring Boot 启动错误问题:elasticsearch-java 8.17.0 报 elasticsearch-rest-cli
    解决SpringBoot启动错误问题:Thefollowingmethoddidnotexistorg.elasticsearch.client.RequestOptions$Builder.setHttpAsyncResponseConsumerFactory异常分析与解决方案在使用SpringBoot应用时,可能会遇到以下启动错误:***************************APPLICATIONF......
  • Linux(Centos 7.6)命令详解:rmdir
    1.命令作用如果目录为空,则删除该目录(RemovetheDIRECTORY(ies),iftheyareempty)2.命令语法Usage:rmdir[OPTION]...DIRECTORY...3.参数详解OPTION:--ignore-fail-on-non-empty,忽略每个因为目录为非空的错误(如果目录非空,不会报错也不会删除非空目录)-p,--parent......
  • Linux(Centos 7.6)命令详解:pwd
    1.命令作用显示当前工作目录的完整路径(PrintWorkingDirectory)2.命令语法Usage:pwd[-LP]3.参数详解-L,显示逻辑路径,遵循符号链接;这是默认选项。-P,显示物理路径,不遵循符号链接。4.常用用例1.-L参数使用,是默认选项,用于不用效果一样。[root@localhost~]#ll/binlrw......
  • Linux(Centos 7.6)命令行快捷键
     Linux(Centos7.6)操作系统一般都是使用命令行进行管理,如何能高效的进行命令编辑与执行,需要我们记住一些常见的命令,也需要连接一些常见快捷键的使用,常见快捷键如下:快捷键快捷键说明tab命令行补齐ctrl+r快速查找之前命令(历史命令),并执行ctrl+a光标移至行首ctrl+e光标移至行......
  • Linux(Centos 7.6)命令详解:ls
    1.命令作用列出目录内容(listdirectorycontents)2.命令语法Usage:ls[OPTION]...[FILE]...3.参数详解OPTION:-l,longlist使用长列表格式-a,all不忽略.开头的条目(打印所有条目,包括.开头的隐藏条目)-t,modificationtime按修改时间排序,最新的优先-r,reverseorderwhile......