Когда я заменяю обслуживаемый файл (или изменяю символическую ссылку) и одновременно загружаю этот файл, Apache редко (в небольшой доле процента) отвечает заголовками из старого файла, но с содержимым из нового файла.
Я тестировал его на нескольких версиях Apache 2.2 (2.2.3, 2.2.22 - Debian стабильный), локально и удаленно, на виртуальных и физических машинах, в разных дистрибутивах (Red Hat, CentOS, Debian) - я всегда мог воспроизвести его, используя Скрипт Python многократно загружает файл в потоках (20-200 потоков) и время от времени заменяет его на сервере (например, каждые 100 мс).
В чем проблема? Это вина Apache или, может быть, я что-то делаю не так?
Обновить: Я также тестировал Nginx, у него этой проблемы нет. Но в редких случаях (в 100 раз реже, чем на Apache) он не видит файл и обслуживает содержимое по умолчанию (404 или страница по умолчанию).
Вместо того, чтобы возиться с файловой системой, я предлагаю изменить конфигурацию сервера, т.е.
DocumentRoot /var/www/version_1
к
DocumentRoot /var/www/version_2
а затем испустить apachectl -k gracefull
. Использование include - это всего лишь небольшой фрагмент, который нужно перезаписать. Очевидно, что все еще существует период, когда некоторые процессы apache могут обслуживать старые файлы со старыми заголовками, а другие - новые файлы с новыми заголовками, но проблемы смешанных заголовков / содержимого возникнуть не должно.
Apache не предназначен для обслуживания динамического контента напрямую из файловой системы. Я бы ожидал таких проблем просто из-за непреднамеренного кеширования в программе. Если вам нужно обслуживать динамический контент, используйте сценарии, CGI или подобное.
В POSIX-совместимых системах переименование выполняется атомарно. Таким образом, должно быть безопасно и последовательно записывать в filename.new, а затем в "mv filename.new filename". Любые открытые дескрипторы в «старом» имени файла будут получать содержимое в старом индексном дескрипторе, а новые запросы получат новый.