如何在 Apache 中原子地替换文件?

如何在 Apache 中原子地替换文件?

当我替换提供的文件(或修改符号链接)并同时下载该文件时,Apache 很少(百分比很小)使用旧文件的标头进行响应,而是使用新文件的内容进行响应。

我在 Apache 2.2(2.2.3、2.2.22 - Debian 稳定版)的几个版本上(本地和远程)、在虚拟机和物理机上、在不同的发行版(Red Hat、CentOS、Debian)上对其进行了测试 - 我总是可以使用 Python 脚本在线程(20-200 个线程)中重复下载文件并不时(比如每 100 毫秒)在服务器上替换它来重现它。

问题出在哪里?是 Apache 的问题还是我做错了什么?

更新:我也测试了 Nginx,它没有这个问题。但在极少数情况下(比 Apache 少 100 倍),它看不到文件并提供默认内容(404 或默认页面)。

答案1

Apache 并非旨在直接从文件系统提供动态内容。我认为此类问题只是由于程序内无意的缓存而导致的。如果您需要提供动态内容,请使用脚本、CGI 或类似程序。

答案2

我建议不要修改文件系统,而是更改服务器配置,即更改

DocumentRoot /var/www/version_1

DocumentRoot /var/www/version_2

然后发出一个apachectl -k gracefull。使用includes,它只是一个您必须覆盖的小片段。显然,仍然有一段时间,一些apache进程可能会使用旧标题提供旧文件,而其他进程使用新标题提供新文件,但混合标题/内容的问题不应该发生。

答案3

在 POSIX 兼容系统上,重命名是原子的。因此,写入 filename.new 然后执行“mv filename.new filename”应该是安全且一致的。“旧”文件名上的任何打开的句柄都将获取旧 inode 上的内容,而新请求将获取新内容。

相关内容