Я использую Apache 2.4.3 в качестве обратного прокси-сервера из-за его соответствия требованиям RFC 2616. Мое приложение использует такие заголовки, чтобы включить кеширование на прокси-сервере:
Cache-Control: public, s-maxage=0
Expires: ... (+1 day)
X-Group: A
Vary: X-Group
ETag: W/"foo1"
После того, как первый запрос нагреет кеш, если мое приложение изменится, чтобы ответить следующим образом:
Cache-Control: public, s-maxage=0
Expires: ... (+1 day)
X-Group: B
Vary: X-Group
ETag: W/"foo2"
Приложение ответит 304 Not Modified, если заголовок If-None-Match от Apache совпадает с ETag, созданным источником. Однако Apache затем кэширует второй ответ 200 и заменяет запись «foo1» с новым ответом вместо кэширования обоих ответов с разными ETag. Поэтому вместо If-None-Match: W/"foo1", W/"foo2"
следующий запрос на повторную валидацию просто If-None-Match: W/"foo2"
. Таким образом, кеш постоянно получает промахи вместо того, чтобы постоянно получать попадания.
Из раздела 12.1 RFC 2616:
Однако исходный сервер не ограничен этими размерами и МОЖЕТ изменять ответ в зависимости от любого аспекта запроса, включая информацию за пределами полей заголовка запроса или внутри полей заголовка расширения, не определенных в этой спецификации.
Я пробовал следующие комбинации для Vary:
Vary: X-Foo
Vary: *
Vary: User-Agent
Я также пробовал как сильные, так и слабые теги ETag, и, что бы ни случилось, я не могу заставить Apache кэшировать два ответа одновременно, он всегда сохраняет по сравнению с предыдущим. Если он не может сохранить более одного варианта страницы, тогда ETag бесполезен, Last-Modified будет так же хорош.
Из документов Apache 2.4:
mod_cache реализует соответствующий RFC 2616 фильтр кэширования содержимого HTTP с поддержкой кэширования согласованных ответов содержимого, содержащих заголовок Vary.
Обратите внимание, что здесь написано «ответы» во множественном числе. Я неправильно интерпретирую спецификацию HTTP или Apache 2.4 просто не полностью поддерживает ETags?
Вы приведете пару таких примеров:
Cache-Control: public, s-maxage=0
Expires: ... (+1 day)
X-Group: A
Vary: X-Group
ETag: W/"foo1"
Я особенно замечаю Vary: X-Group
заголовок. Является X-Group
заголовок запроса или заголовок ответа?
Согласно RFC 2616 раздел 14.44, Vary
следует перечислить любые запрос заголовки, которые приведут к другому представлению содержимого по сравнению с исходным сервером. Из вашего примера я подозреваю X-Group
может быть заголовком ответа, и в этом случае mod_cache не будет хранить несколько версий данного ресурса.
Вы могли бы попробовать установить Vary: If-None-Match
, что позволит mod_cache хранить версию ресурса для каждого ETag. По общему признанию, я этого не пробовал. Если предположить, что это работает, то одним из недостатков является то, что первый запрос от любого клиента будет промахом в кэше.