apache mod_cache в v2.2 - включить кеш на основе URL
Мы используем 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 запросов / с в пиковое время. Иногда наши чтения IO ждут всплесков. Это не становится действительно медленным, но мы пытаемся настроить его для лучшей производительности.
В 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 (по умолчанию CacheIgnoreCacheControl отключено). А перед тем просто установите RequestHeader на основе запроса. Если это не запрос изображения, установите заголовок Cache-control, чтобы он вообще обходил кеш.
Это не работает, я думаю, из-за поздней обработки директивы RequestHeader, см. https://httpd.apache.org/docs/2.2/mod/mod_headers.html
Я не могу добавить раннюю обработку, поскольку ключевое слово "early" не может использоваться вместе с условным "env=! Image"
Я не могу изменить URL, запрашивающий изображения, и я знаю, что, конечно, есть и другие решения. Но меня интересует только настройка apache2.2 для достижения моей цели.
У кого-нибудь есть идеи, как достичь моей цели?
1 ответ
https://httpd.apache.org/docs/2.2/mod/mod_cache.html
Переменная среды без кэширования может быть установлена для отключения кэширования на более мелком наборе ресурсов в версиях 2.2.12 и более поздних.
Таким образом, вы должны иметь возможность отключить кэширование для всего, кроме запросов, заканчивающихся на.png с
SetEnvIf Request_URI !\.png$ no-cache