Вопрос или проблема
Я дергал себя за волосы с этим с вчерашнего дня, я пытаюсь настроить mod_cache для кэширования определенных файлов javascript, используя следующую конфигурацию, добавленную в раздел конфигурации моего виртуального хоста:
<IfModule mod_cache.c>
<IfModule mod_cache_disk.c>
CacheRoot /var/cache/apache24/mod_cache_disk
CacheQuickHandler off
CacheIgnoreQueryString On
<LocationMatch "chunk-.+\.js$">
CacheEnable disk
CacheHeader on
CacheDetailHeader on
CacheMaxFileSize 25000000
CacheDefaultExpire 86400
</LocationMatch>
</IfModule>
</IfModule>
Файлы правильно добавляются в кэш, что видно по заголовкам http-запросов и выводу htcacheclean -a -p /var/cache/apache24/mod_cache_disk/
:
GET https://example.com/en/chunk-WXIYG2YB.js
HTTP/2 200
last-modified: Sun, 01 Sep 2024 20:39:11 GMT
etag: "114a-62114d11a75eb-gzip"
accept-ranges: bytes
vary: Accept-Encoding
content-encoding: gzip
x-robots-tag: noindex
x-cache: MISS from mydomain.com
x-cache-detail: "cache miss: attempting entity save" from mydomain.com
content-type: application/javascript
date: Wed, 04 Sep 2024 10:35:43 GMT
server: Apache/2.4.59 (FreeBSD) OpenSSL/1.1.1t-freebsd
X-Firefox-Spdy: h2
и кэша:
https://example.com:443/en/chunk-IUI5V3WX.js?
https://example.com:443/en/chunk-IUI5V3WX.js?
https://example.com:443/en/chunk-WXIYG2YB.js?
https://example.com:443/en/chunk-WXIYG2YB.js?
...
Как видно, помимо того, что есть дубликаты, к ключу кэша добавляется символ “?”, который, как я подозреваю, может привести к пропускам кэша, даже несмотря на то, что я добавил настройку CacheIgnoreQueryString.
Все запросы, которые должны попадать в кэш, приводят к “cache miss: attempting entity save”. Я был бы очень признателен за любую помощь или идеи на данный момент.
Заранее спасибо
По какой-то причине добавление параметра конфигурации CacheIgnoreCacheControl on
похоже решает проблему: теперь кэш используется, но я не понимаю, почему этот параметр необходим, поскольку заголовки, предотвращающие кэширование, не отправляются. Мне не очень нравится это решение, так как это скорее обходной путь с неприятным побочным эффектом, делающим заголовок Cache-Control непригодным.
Сначала снова прочитайте документацию для htcacheclean
. Символ ?
объяснен там.
Чтобы отладить дублирующиеся кеш-файлы: кроме заголовков ответа, которые вы вставили выше, вам также нужно посмотреть на заголовки запроса. Настройте свой журнал доступа так, чтобы записывать куки, например.
Другой возможной причиной может быть CacheQuickHandler off
.
Когда речь заходит о httpd, действительно очень мало поведений, которые нельзя объяснить после внимательного чтения документации, чтобы узнать, что делает каждая директива.
Ответ или решение
Конечно, давайте разберем вашу проблему с кешированием в Apache с использованием mod_cache
.
Судя по предоставленной информации, проблема действительно связана с добавлением символа "?" к ключам кеша. Это может привести к тому, что все запросы воспринимаются как уникальные, даже если фактически это один и тот же ресурс, тем самым вызывая кэш-промахи.
Объяснение проблемы
- Символ "?" в URL: Ваша конфигурация имеет директиву
CacheIgnoreQueryString On
, что означает, что запросы с различными параметрами запроса (все части после "?") должны игнорироваться, но кэш все равно может добавлять этот символ, создавая дубликаты кеша. - Отсутствие соответствующих заголовков: Без правильных заголовков, указывающих на то, что ресурс может быть закеширован, Apache может считать необходимость создания новых записей в кэше.
- Директива
CacheQuickHandler off
: Эта директива может повлиять на работу кеширования, так как уменьшает производительность. Рекомендуется использоватьCacheQuickHandler on
для более быстрой обработки запросов к кэшу.
Решение
-
Проверьте конфигурацию кэширования:
Убедитесь, что у вас нет других модулей, которые могут конфликтовать сmod_cache
, напримерmod_expires
илиmod_headers
, которые могли бы устанавливать заголовки, блокирующие кеширование. -
Измените директиву
CacheQuickHandler
:
Попробуйте изменитьCacheQuickHandler off
наCacheQuickHandler on
и проверьте, изменится ли поведение кеша. -
Добавьте директиву
CacheIgnoreCacheControl on
с осторожностью:
Хотя вы указали, что эта директива помогает решить проблему, будьте осторожны с её использованием. Эта установка игнорирует заголовки Cache-Control от серверов, что может привести к кешированию содержимого, которое не должно кешироваться. Если вы решите оставить эту директиву, убедитесь, что вы тестируете результат в различных сценариях. -
Обновите настройки журналов:
Настройте журнал доступа, чтобы записывать заголовки запросов; это поможет вам лучше понять, какие параметры добавляются к запросам, приведя к дублированию кеша. Например:LogFormat "%h %l %u %t \"%r\" %>s %b \"%{User-Agent}i\" \"%{Referer}i\" \"%{Cookie}i\"" combined
Включите
Cookie
в журналы, так как наличие или отсутствие куки также может влиять на кэширование. -
Используйте
htcacheclean
для очистки кеша:
Если у вас есть дублированные ключи, периодически очищайте кеш с помощью инструментаhtcacheclean
, чтобы избежать накопления ненужных повторов. -
Тестирование:
Всегда тестируйте изменения в настройках в среде разработки или на тестовых серверах перед переносом в рабочую. Убедитесь также, что текущее поведение соответствует вашим ожиданиям, проверяя заголовки кэширования, которые возвращаются с сервера.
Заключение
Кеширование может быть сложной темой, особенно когда накладываются различные модули и настройки. Внимательное чтение документации mod_cache
и тестирование изменений в конфигурации должны помочь вам справиться с проблемами кэширования. Если проблема сохранится, возможно, стоит обратиться к сообществу разработчиков Apache для получения более детальной помощи.