Мы используем apache2.2 в качестве интерфейсного сервера с серверами приложений в качестве обратных прокси позади apache.
Мы используем mod_cache
для некоторых изображений и включил его так:
<IfModule mod_disk_cache.c>
CacheEnable disk /
CacheRoot /var/cache/apache2/mod_disk_cache
CacheIgnoreCacheControl On
CacheMaxFileSize 2500000
CacheIgnoreURLSessionIdentifiers jsessionid
CacheIgnoreHeaders Set-Cookie
</IfModule>
URL-адреса изображений полностью различаются и не имеют общего начального шаблона, но все они заканчиваются на «.png». Вот почему мы использовали корень в CacheEnable /
Если не обслуживается из кеша, запрос направляется на сервер приложений через обратный прокси. Пока все хорошо, кеш работает нормально.
Но мне действительно нужно кешировать все запросы изображений, заканчивающиеся на «.png». Моя приведенная выше конфигурация все еще работает, поскольку мой сервер приложений отправляет соответствующий заголовок Cache-Control: no-cache на обратном пути в apache. Таким образом, большинство страниц отправляют обратно заголовок без кеширования, и они вообще не кэшируются. Мои ответы «.png» не отправляют заголовок Cache-Control, поэтому apache будет кэшировать все URL-адреса только с «.png». Хорошо.
Но когда новый запрос поступает в apache, apache не знает, что следует рассматривать только запросы .png, поэтому каждый запрос проверяет файл на диске (записанный с strace -e trace=file -p pid
):
[pid 19063] open("/var/cache/apache2/mod_disk_cache/zK/q8/Kd/g6OIv@woJRC_ba_A.header", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
Я не хочу, чтобы apache записывал каждый запрос на диск, поскольку большинство запросов вообще не кэшируется. И у нас до 10.000 запросов в секунду в пиковое время. Иногда наши читаемые всплески ожидания ввода-вывода. Он не сильно замедляется, но мы пытаемся настроить его для повышения производительности.
В apache 2.4 вы можете сказать:
<LocationMatch .png$>
CacheEnable disk
</LocationMatch>
Это невозможно в версии 2.2, и, поскольку я не вижу резервных копий для debian, я не собираюсь обновляться.
Итак, я попытался настроить apache2.2, чтобы он следовал своим правилам:
<IfModule mod_disk_cache.c>
SetEnvIf Request_URI "\.png$" image
RequestHeader unset Cache-Control
RequestHeader append Cache-Control no-cache env=!image
CacheEnable disk /
CacheRoot /var/cache/apache2/mod_disk_cache
#CacheIgnoreCacheControl on
CacheMaxFileSize 2500000
CacheIgnoreURLSessionIdentifiers jsessionid
CacheIgnoreHeaders Set-Cookie
</IfModule>
Идея состоит в том, чтобы позволить apache принимать решение об обслуживании запроса из кеша на основе заголовка Cache-control (CacheIgnoreCacheControl по умолчанию выключен). А перед этим просто установите RequestHeader на основе запроса. Если это не запрос изображения, установите заголовок Cache-control, чтобы он вообще обходил кеш.
Это не работает, я думаю, из-за поздней обработки директивы RequestHeader, см. https://httpd.apache.org/docs/2.2/mod/mod_headers.html#early
Я не могу добавить раннюю обработку, так как ключевое слово "Early" нельзя использовать вместе с условным "env =! Image"
Я не могу изменить URL-адрес, запрашивающий изображения, и я знаю, что, конечно, есть другие решения. Но меня интересует только настройка apache2.2 для достижения моей цели.
Есть ли у кого-нибудь идеи, как достичь моей цели?
https://httpd.apache.org/docs/2.2/mod/mod_cache.html#cachedisable
Переменная среды без кеширования может быть установлена для отключения кеширования более детализированного набора ресурсов в версиях 2.2.12 и более поздних.
Таким образом, вы должны иметь возможность отключить кеширование для всего, кроме запросов, заканчивающихся на .png с
SetEnvIf Request_URI !\.png$ no-cache