草庐IT

PHP session导致varnish不缓存

coder 2024-04-17 原文

我正在努力理解 varnish 的行为,希望有人能给出一些启示。

我正在做一个测试,我试图让 Varnish 缓存带有 cookie 的请求/响应。

我有一个非常简单的 PHP 脚本,它可以简单地启动一个 session 。

<?php session_start(); ?>

我确实希望 varnish 不会因 Set-CookieCookie header 而缓存。

我将去取消设置这些 header :

sub vcl_backend_response {
    unset beresp.http.set-cookie;
}

sub vcl_recv {
    unset req.http.cookie;
}

请求的页面仍然没有被缓存

我知道 PHP 会发送缓存清除 header ,varnish 可能会遵守该 header 。让我们检查一下:

<?php echo session_cache_limiter(); ?>

输出:无缓存

来自 session_cache_limiter()文档中已知 nocache 将发送这些响应 header 以破坏缓存:

Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache

让我们取消设置它们:

sub vcl_backend_response {
    unset beresp.http.expires;
    unset beresp.http.pragma;
    unset beresp.http.cache-control;
    unset beresp.http.set-cookie;
}

此时我希望 varnish 进行缓存,但仍然没有缓存

解决方法是设置一个 ttl:

sub vcl_backend_response {
    unset beresp.http.expires;
    unset beresp.http.pragma;
    unset beresp.http.cache-control;
    unset beresp.http.set-cookie;

    # THIS MADE VARNISH TO CACHE
    set beresp.ttl = 10m;
}

现在问题:

如果默认值为 2m(下面 CLI 中的 -t 120)并且所有缓存清除 header 都已处理,为什么我需要显式设置 TTL?

/usr/sbin/varnishd -P /var/run/varnish.pid -f /etc/varnish/default.vcl -a :80 -T 0.0.0.0:6082 -t 120 -u varnish -g varnish -S /etc/varnish/secret -s malloc,512M

我错过了什么吗?有没有不同的方法,无需设置 TTL(我更喜欢)?

最佳答案

问题是 Varnish 在 vcl_backend_response 被调用之前评估了 Expires 后端响应 header 。结果是传递给 vcl_backend_response 的对象已经有一个过期的 TTL(假设 header 有一个过期日期)。下一个客户端请求将命中缓存的对象,但由于对象已过期 (HIT-FOR-PASS) 而未命中。是的,您正在取消设置 Expires header (通过 unset beresp.http.expires;),但到那时为时已晚。

现在我不确定这是一个错误,还是 Varnish 开发人员对 RFC 的解释。

我知道你的代码可能只是为了测试目的,但你最好不要在 VCL 中与缓存 header 作斗争。使用适当的值(publicprivatenocache)调用 PHP 的 session_cache_limiter(),或者禁用它( session_cache_limiter('')) 并自行控制 header 。

如果您使用的是 PHP session ,您仍然必须处理使其无法缓存的 cookie header ,但那是超出问题范围的另一个问题。

关于PHP session导致varnish不缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31615143/

有关PHP session导致varnish不缓存的更多相关文章

  1. ruby - 如何在 Ubuntu 中清除 Ruby Phusion Passenger 的缓存? - 2

    我试过重新启动apache,缓存的页面仍然出现,所以一定有一个文件夹在某个地方。我没有“公共(public)/缓存”,那么我还应该查看哪些其他地方?是否有一个URL标志也可以触发此效果? 最佳答案 您需要触摸一个文件才能清除phusion,例如:touch/webapps/mycook/tmp/restart.txt参见docs 关于ruby-如何在Ubuntu中清除RubyPhusionPassenger的缓存?,我们在StackOverflow上找到一个类似的问题:

  2. ruby-on-rails - Ruby on Rails 计数器缓存错误 - 2

    尝试在我的RoR应用程序中实现计数器缓存列时出现错误Unknownkey(s):counter_cache。我在这个问题中实现了模型关联:Modelassociationquestion这是我的迁移:classAddVideoVotesCountToVideos0Video.reset_column_informationVideo.find(:all).eachdo|p|p.update_attributes:videos_votes_count,p.video_votes.lengthendenddefself.downremove_column:videos,:video_vot

  3. Ruby 守护进程导致 ActiveRecord 记录器 IOError - 2

    我目前正在用Ruby编写一个项目,它使用ActiveRecordgem进行数据库交互,我正在尝试使用ActiveRecord::Base.logger记录所有数据库事件具有以下代码的属性ActiveRecord::Base.logger=Logger.new(File.open('logs/database.log','a'))这适用于迁移等(出于某种原因似乎需要启用日志记录,因为它在禁用时会出现NilClass错误)但是当我尝试运行包含调用ActiveRecord对象的线程守护程序的项目时脚本失败并出现以下错误/System/Library/Frameworks/Ruby.frame

  4. ruby - 从另一个私有(private)方法中使用 self.xxx() 调用私有(private)方法 xxx,导致错误 "private method ` xxx' called” - 2

    我正在尝试获得良好的Ruby编码风格。为防止意外调用具有相同名称的局部变量,我总是在适当的地方使用self.。但是现在我偶然发现了这个:classMyClass上面的代码导致错误privatemethodsanitize_namecalled但是当删除self.并仅使用sanitize_name时,它会起作用。这是为什么? 最佳答案 发生这种情况是因为无法使用显式接收器调用私有(private)方法,并且说self.sanitize_name是显式指定应该接收sanitize_name的对象(self),而不是依赖于隐式接收器(也是

  5. ruby - 为什么 return 关键字会导致我的 'if block' 出现问题? - 2

    下面的代码工作正常:person={:a=>:A,:b=>:B,:c=>:C}berson={:a=>:A1,:b=>:B1,:c=>:C1}kerson=person.merge(berson)do|key,oldv,newv|ifkey==:aoldvelsifkey==:bnewvelsekeyendendputskerson.inspect但是如果我在“ifblock”中添加return,我会得到一个错误:person={:a=>:A,:b=>:B,:c=>:C}berson={:a=>:A1,:b=>:B1,:c=>:C1}kerson=person.merge(berson

  6. ruby-on-rails - 什么会导致与 APNS 的连接间歇性断开连接? - 2

    我有一个ruby​​脚本可以打开与Apple推送服务器的连接并发送所有待处理的通知。我看不出任何原因,但当Apple断开我的脚本时,我遇到了管道损坏错误。我已经编写了我的脚本来适应这种情况,但我宁愿只是找出它发生的原因,这样我就可以在第一时间避免它。它不会始终根据特定通知断开连接。它不会以特定的字节传输大小断开连接。一切似乎都是零星的。您可以在单个连接上发送的数据传输或有效负载计数是否有某些限制?看到人们的解决方案始终保持一个连接打开,我认为这不是问题所在。我看到连接在3次通知后断开,我看到它在14次通知后断开。我从未见过它能超过14点。有没有人遇到过这种类型的问题?如何处理?

  7. ruby-on-rails - bundle 安装尝试使用缓存文件 - 2

    当我尝试进行bundle安装时,我的gem_path和gem_home指向/usr/local/rvm/gems/我没有写入权限,并且由于权限无效而失败。因此,我已将两个路径都更改为我具有写入权限的本地目录。这样做时,我进行了bundle安装,我得到:bruno@test6:~$bundleinstallFetchinggemmetadatafromhttps://rubygems.org/.........Fetchinggemmetadatafromhttps://rubygems.org/..Bundler::GemspecError:Couldnotreadgemat/afs/

  8. ruby - 在多个线程中引用类方法会导致自动加载循环依赖崩溃 - 2

    代码:threads=[]Thread.abort_on_exception=truebegin#throwexceptionsinthreadssowecanseethemthreadseputs"EXCEPTION:#{e.inspect}"puts"MESSAGE:#{e.message}"end崩溃:.rvm/gems/ruby-2.1.3@req/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:478:inload_missing_constant':自动加载常量MyClass时检测到循环依赖稍加研究后,

  9. ruby-on-rails - Heroku Action 缓存似乎不起作用 - 2

    我一直在Heroku上尝试不同的缓存策略,并添加了他们的memcached附加组件,目的是为我的应用程序添加Action缓存。但是,当我在我当前的应用程序上查看Rails.cache.stats时(安装了memcached并使用dalligem),在执行应该缓存的操作后,我得到current和total_items为0。在Controller的顶部,我想缓存我有的Action:caches_action:show此外,我修改了我的环境配置(对于在Heroku上运行的配置)config.cache_store=:dalli_store我是否可以查看其他一些统计数据,看看它是否有效或我做错

  10. ruby-on-rails - rails expire_page 没有删除缓存的文件 - 2

    我有一个具有页面缓存的ControllerAction,我制作了一个清扫程序,它使用Controller和指定的Action调用expire_page...Controller操作呈现一个js.erb模板,所以我试图确保expire_page删除public/javascripts中的.js文件,但它没有这样做。classJavascriptsController"javascripts",:action=>"lol",:format=>'js')endend...所以,我访问javascripts/lol.js并呈现我的模板。我验证了public/javascripts/lol.js

随机推荐