Я думал о том, чтобы спросить Рекомендации по использованию программного обеспечения, но потом я узнал, что это может быть слишком странная просьба, и сначала ей нужно уточнить.
Мои баллы:
- Каждый ответ содержит
etag
- который является хешем содержимого
- и который глобально уникален (с достаточной вероятностью)
- Содержимое (в основном) динамическое и может меняться в любое время (
expires
иmax-age
здесь бесполезны заголовки). - Содержимое частично зависит от пользователя, как указано разрешениями (которые сами иногда меняются).
В принципе, прокси должен содержать кеш, сопоставляющий etag
с контентом ответа. etag
получается с сервера и в наиболее распространенном случае сервер вообще не занимается контентом ответа.
Он должен выглядеть следующим образом: прокси всегда отправляет запрос на сервер, а затем
- 1 сервер возвращает только
etag
, а прокси-сервер выполняет поиск по нему и- 1.1 при ударе кеша,
- он считывает данные ответа из кеша
- и отправляет ответ клиенту
- 1.2 при пропуске кеша,
- он снова запрашивает сервер, а затем
- сервер возвращает ответ с содержимым и
etag
, - прокси хранит его в кеше
- и отправляет ответ клиенту
- 1.1 при ударе кеша,
- 2 или сервер возвращает ответ с содержимым и
etag
,- прокси хранит данные в кеше
- и отправляет ответ клиенту
Для простоты я отказался от обработки заголовка if-none-match
, что довольно очевидно.
Моя причина в том, что наиболее распространенный случай 1.1 может быть очень эффективно реализован на сервере (используя его запросы на сопоставление кеша на etags
, содержимое не кэшируется на сервере), так что большинство запросов могут быть обрабатывается без сервера, работающего с контентом ответа. Это должно быть лучше, чем сначала получать содержимое из бокового кеша, а затем обслуживать его.
В случае 1.2 на сервер есть два запроса, что звучит плохо, но не хуже, чем сервер запрашивает боковой кеш и получает промах.
Q1: Интересно, как сопоставить первый запрос HTTP. В случае 1 это похоже на запрос HEAD. В случае 2 это похоже на GET. Решение между ними зависит от сервера: если он может обслуживать etag
без вычисления содержимого, то это случай 1, в противном случае это случай 2.
Q2: Есть ли обратный прокси-сервер, который делает что-то вроде этого? Я читал о nginx, HAProxy и Varnish, и, похоже, это не так. Это приводит меня к Q3:. Это плохая идея? Почему?
Q4: Если нет, то какой существующий прокси проще всего адаптировать?
Пример
Запрос GET, такой как /catalog/123/item/456
от пользователя U1
, был подан с некоторым содержимым C1
и etag: 777777
. Прокси хранит C1
под ключом 777777
.
Теперь тот же запрос поступает от пользователя U2
. Прокси перенаправляет его, сервер возвращает только etag: 777777
, а прокси-серверу повезло, находит C1
в кеше (case 1.1) и отправляет его в U2
. В этом примере ни клиенты, ни прокси-сервер не знали ожидаемого результата.
Интересной частью является то, как сервер мог знать etag
без вычисления ответа. Например, у него может быть правило, указывающее, что запросы этой формы возвращают одинаковый результат для всех пользователей, предполагая, что данному пользователю разрешено его видеть. Поэтому, когда пришел запрос из U1
, он вычислил C1
и сохранил etag
под ключом /catalog/123/item/456
. Когда тот же запрос пришел из U2
, он просто подтвердил, что U2
разрешено видеть результат.