告诉 Nginx 不要根据上游的响应头进行缓存

告诉 Nginx 不要根据上游的响应头进行缓存

我正在使用 Nginx 来服务 MediaWiki,并且使用 FastCGI 缓存来避免不必要的 PHP 调用。

(在 MediaWikiLocalSettings.php文件中,我有$wgUseCdn = true;而在 Nginx 配置中,我使用fastcgi_cache和相关的配置选项。)

问题是,MediaWiki/PHP(又称上游)的许多 HTTP 响应都包含Vary标头User-Agent。由于用户代理字符串非常详细且变化多端,这可能会使 Nginx 不必要地缓存大量相同页面的副本,并且很少向新访问者提供缓存版本。

我可以为 Nginx FCGI 缓存提供整整 12 GiB 的空间,并且它会将其全部填满,但我怀疑由于这个问题它大部分都是垃圾,并且只有一小部分缓存内容实际上是有用的。

我想告诉 Nginx FastCGI 缓存不是Vary如果从 MediaWiki PHP 代码发回的响应头包含,则缓存响应User-Agent

(PHP 发回的许多资源也不会根据用户代理而变化,并且 Nginx 仍然可以缓存这些资源。)

我尝试了以下方法,但似乎不起作用:

# In the http context:
map $sent_http_vary $fcgi_nocache {
  default 0;
  "~*user-agent" 1;
}

# In a location *.php context:
add-header X-Fcgi-Nocache $fcgi_nocache;
# Or, if it worked fine, to actually make the nocache take effect:
fastcgi_no_cache $fcgi_nocache;

这使我能够检查X-Fcgi-NocacheHTTP 客户端(例如 Web 浏览器)收到的标头,以查看指令是否map执行了我想要的操作,但值始终不变,0所以我猜$sent_http_vary变量没有按照我希望的方式工作。

有什么办法可以让它工作吗?

答案1

我不知道之前我做错了什么,但突然它就正常工作了。也许我输入的是"*~user-agent""~*user-agent"或者可能是类似的愚蠢的拼写错误,但目前它似乎按预期工作。

话虽如此,根据#nginxLibera 的 IRC 频道中某人的建议,我现在也将其更改为使用变量$upstream_http_vary而不是。这可能更可靠,尽管它似乎也$sent_http_vary适用于变体。$sent_xyz

另外,我注意到 MediaWiki 要么Vary根本没有指定标题,要么指定了包含的标题User-Agent,因此实际上不需要该map指令,尽管知道有这种可能性是件好事。

简而言之,简单的解决方案:

# In location context, where fastcgi_pass and fastcgi_cache are specified:
fastcgi_no_cache $upstream_http_vary;

如果需要,可以采用更精细的解决方案,例如检查Vary标题User-Agent

# In http context, where fastcgi_cache_path is specified:
map $upstream_http_vary $fcgi_nocache {
  default 0;
  "~*user-agent" 1;
}
# In location context, where fastcgi_pass and fastcgi_cache specified:
fastcgi_no_cache $fcgi_nocache;

相关内容