【问题标题】:How to make mod_cache work properly with dynamic content?如何使 mod_cache 与动态内容一起正常工作?
【发布时间】:2013-07-25 09:26:56
【问题描述】:

我正在尝试使用 mod_cache 来缓存动态生成的内容。这是我的 Apache 配置:

CacheEnable mem /
MCacheSize 4096
MCacheMaxObjectCount 100
MCacheMinObjectSize 1
MCacheMaxObjectSize 2048
CacheIgnoreCacheControl On
CacheIgnoreNoLastMod On
CacheStorePrivate On
CacheStoreNoStore On

<Location /cgi-bin>
    SetHandler cgi-script
    Options +ExecCGI
</Location>

这是一个 CGI 脚本(仅用于测试):

#!/opt/app/phantomjs/bin/phantomjs
var date = new Date('Sun, 01 Jan 2012 00:00:00 GMT');
console.log('Last-Modified: '+ date.toUTCString());
console.log('Cache-Control: max-age=' + (365 * 24 * 60 * 60)+ ', public');
date.setDate(date.getDate() + 365);
console.log('Expires: '+ date.toUTCString() + '\n\n');

// lengthy operation here...

console.log(content);

这基本上有效。但是会发生什么,如果客户端请求带有If-Modified-Since 标头的 cgi-bin:

  1. CGI 脚本流标头
  2. 延迟几秒
  3. CGI 脚本流正文
  4. Apache 发送 304

这对我来说毫无意义。 Apache 在发送未修改的响应之前等待整个响应。

我的预期

  1. CGI 脚本流标头
  2. Apache 发送 304
  3. CGI 脚本被取消或 CGI 脚本主体被丢弃

有什么办法可以解决吗?

【问题讨论】:

  • 另外,我刚刚发现当我的cgi脚本显式设置Status: 200时,mod_cache似乎根本没有任何效果,但是如果cgi没有发送状态标头,它会发送304

标签: apache caching cgi


【解决方案1】:

CGI 脚本应更改如下。

  1. 不要使用静态的上次修改日期。动态资源的 Last-Modified 应该设置为当前执行时间。

  2. 缓存控制指令包含类型错误“pulic”应该是“public”

  3. 不需要Expires 指令,因为Cache-Control 的优先级高于Expires。

您在发送标头后的预期行为“终止 CGI 脚本”是不可能的。如果您的缓存有效,则在缓存条目无效之前不会执行 CGI 脚本。

【讨论】:

  • 1.以上只是为了测试。但问题的重点是last-modified 在两个请求之间可能发生了变化,也可能没有变化(想象连接不同的文件......) 2. 谢谢你,但没有改变任何东西。 3. 为了更加安全,我更喜欢保留Expires。 4.“在缓存条目无效之前不会执行CGI脚本”这应该如何与if-modified-since一起工作?
  • Aaaah - 现在我明白你的意思了。如果您的资源没有更改,您的 CGI 脚本应该发送状态 304,并中止进一步(正文)处理。来自 apache doc:当源服务器收到条件请求时,源服务器应根据请求检查 ETag 或 Last-Modified 参数是否已更改。如果不是,则源应以简洁的“304 Not Modified”响应进行响应。这会向缓存发出信号,表明陈旧的内容仍然是新鲜的,应该用于后续请求,直到再次达到内容的新新鲜度生命周期
  • 如果条目仍然有效(时间有效)并且 cache_control(原始响应)不包含“必须重新验证”指令,则 mod_cache 满足条件客户端请求“if-modified-since” .顺便说一句:你使用什么 apache 版本?
  • 对。虽然 Apache 很好地满足了“源服务器应该检查 ETag 或 Last-Modified 参数是否已更改”的要求,但它通过等待完整的响应来做到这一点。这使得缓存无用。我用的是 2.2 版,但还不如用 2.4 版
  • ...“这会使缓存变得无用”-我不敢相信,所以我尝试了一下-是的,您是对的-在这种组合中完全没用:-(。我做了一些进一步的研究为什么我之前在我的项目中从未见过这种行为并找到了答案 - 因为我们正在将动态资源请求转发到其他服务器实例,然后 mod_cache 将起作用。请参阅我下一篇文章中的示例
【解决方案2】:

这是我在上一条评论中所说的解决方案。将 CGI 执行转发到内部虚拟主机。使用此配置 mod_cache 将按预期工作。我在我的机器上使用 apache 2.2.21 对其进行了测试。

# virtual cgi host - used internally only for cgi execution
<VirtualHost *:8080>
    ##ServerAdmin postmaster@dummy-host.localhost
    DocumentRoot "C:/Project/web"
    ServerName cgi-bin.local
    ErrorLog "logs/cgi-bin-error.log"
    CustomLog "logs/cgi-bin-access.log" combined
    LogLevel debug

    <Location /cgi-bin>
        SetHandler cgi-script
        Options +ExecCGI
    </Location>

</VirtualHost>

# Virtual host used by client
<VirtualHost *:8080>
    ##ServerAdmin postmaster@dummy-host.localhost
    DocumentRoot "C:/Project/web"
    ServerName web.local
    ErrorLog "logs/web-error.log"
    CustomLog "logs/web-access.log" combined

    CacheEnable mem /
    MCacheSize 4096
    MCacheMaxObjectCount 100
    MCacheMinObjectSize 50
    MCacheMaxObjectSize 20480
    MCacheMaxStreamingBuffer 20480
    CacheIgnoreCacheControl On
    CacheIgnoreNoLastMod On
    CacheStorePrivate On
    CacheStoreNoStore On

    ProxyRequests Off
    ProxyPass /cgn-bin http://cgi-bin.local:8080/
    ProxyPassReverse /cgn-bin http://cgi-bin.local:8080/

</VirtualHost>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-05
    • 1970-01-01
    • 2020-06-09
    • 2021-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多