Vagrant/VirtualBox/Apache2 奇怪的缓存行为

66

我使用Vagrant创建了一个基于Ubuntu的VirtualBox虚拟机,并安装了Apache2。

其中,网页服务器会从我的/vagrant目录中提供静态文件。

这通常是正常工作的。但是当我更改共享文件夹中的图片并重新加载网站时,旧版本的图片被提供,但被截断了。

如果我首先从共享文件夹中删除旧图片,刷新网站以确保不显示该图片,然后保存新文件并再次重新加载网站,则可以解决该问题。

是否有人知道这个问题?我没有安装任何特殊的内容,只安装了Apache 2与mod_rewrite、带有MongoDB、APC插件和MongoDB的PHP,以及带有一堆脚本的nodeJS。


1
我曾经遇到过同样的问题,但是是在一个文本(json)文件中。在尝试了Nginx并发现它和Apache有相同的问题之后,我才能够进行足够特定的搜索以找到这个答案。 - Nathan Long
6个回答

134

这里找到了答案:

JC,

你看到的可能是因为提供静态文件的服务器正在使用“sendfile()”系统调用,在VirtualBox文件系统中存在问题。您需要禁用服务器中的sendfile()。对于Apache:

EnableSendfile off

对于nginx:

sendfile off;

最好的解决方法是关闭sendfile()。

Mitchell


3
我看到你的解答可以解释这个奇怪的问题。值得一提的是,如果你使用NFS共享文件,那将是一种更可靠和更快的解决方案,并且不会遇到这个特定的问题:http://vagrantup.com/v1/docs/nfs.html - Gerry
18
天哪,非常感谢您发布这个。我已经试图剃这只牦牛整整一天了。 :D - Nathan Long
4
非常感谢您。我希望能把过去四个小时的时间重新拿回来。 - Deinumite
2
非常感谢您。 - Deinumite
3
@NathanLong 的“shave this yak”值得一赞。 - James Furey
显示剩余5条评论

8
这让我很疑惑!感谢Philipp的发布。对于那些不知道如何更改配置文件的人,这就是我所做的:
要找到文件:$ sudo find -name "nginx.conf" 我的在这里:./etc/nginx/nginx.conf 所以我运行了这个命令来修改它:$ sudo nano ./etc/nginx/nginx.conf 将包含sendfile on;的行更改为sendfile off; 别忘了退出vagrant reload

在更改sendfile时有一个错别字,应该切换为关闭,对吧? - user49438

7
这是VirtualBox中的旧漏洞(参见:#819#9069#12597#14920),其中vboxvfs似乎存在一些与同步文件的mmapped访问有关的问题。
当您在VM之外编辑文件并希望在VM中看到相同的更改时,可能会发生这种情况。
为解决此问题,您需要禁用内核sendfile支持以通过禁用EnableSendfile选项将文件传递给客户端,在httpd.conf或vhosts文件中禁用它。
<Directory "/path-to-nfs-files">
  EnableSendfile Off
</Directory>

这对于NFS或SMB挂载的文件尤其麻烦。更改后重新加载Apache。

对于Nginx类似(在nginx.conf中),例如。

sendfile off;

另一个解决方法是记住不要在主机上编辑文件,或尝试在虚拟机内重新编辑同一文件。


另一个解决方法包括丢弃Linux页面缓存,例如:

echo 1 > /proc/sys/vm/drop_caches

如果想每秒清除缓存(根据这篇帖子),请尝试以下操作:

watch -n 1 $(sync; echo 1 > /proc/sys/vm/drop_caches)

注意:数字1代表释放页面缓存,2代表释放目录项和索引节点,3代表同时释放页面缓存、目录项和索引节点。


可以通过以下mmap-test程序复制上述问题,请参见:mmap-problem.c


1
可以确认在Vagrant/VirtualBox设置中,echo 1 > /proc/sys/vm/drop_caches 命令可以解决该问题。这似乎是一个已知的问题:https://www.virtualbox.org/ticket/9069 至少已经存在六年了。 - jevon

4
我遇到了与VirtualBox/Docker/Nginx环境类似的问题。
使用命令echo 1 > /proc/sys/vm/drop_caches可以解决问题,但看起来有些笨拙。
nginx.conf中加入指令sendfile off;并不能解决问题,我尝试将其与指令expires off;一起使用,这样做是成功的。
因此,我的解决方案如下:
sendfile off;
expires off;

3
如果你正在使用Laravel 5、Barryvdh的Debugbar和通过gulp.watch使用browserSync,你可能会遇到这个错误。我因为browser Sync代理请求的方式而遇到了完全相同的错误。如果我通过http://127.0.0.1:3000/laravel/page 查看我的开发服务器,就会出现错误,但是通过http://127.0.0.1/laravel/page 就没有错误了。
我已经向我们在browserSync的朋友们报告了这个问题,他们做得很好。所以这更像是一个原因而不是一个解决方案,但是在浪费更多时间之前,请先测试一下是否存在这个问题。
这个问题也类似于这篇文章中发现的错误

0

这也是在CentOS/VirtualBox配置中关于CSS文件出现奇怪行为的原因之一。

你可以更改/vagrant文件夹中CSS文件的内容,浏览器会显示状态码200(而不是304),表示它知道该文件是新的。但内容并没有更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接