Я кеширую динамически генерируемые страницы (PHP-FPM, NGINX) и перед ними лак, это работает очень хорошо.
Однако, как только тайм-аут кэша достигнут, я вижу это:
- страница новых запросов клиентов
- лак распознает тайм-аут кэша
- клиент ждет
- лак выбирает новую страницу из бэкэнда
- Лак доставляет новую страницу клиенту (и имеет страницу в кеше, также для следующего запроса, который получает его мгновенно)
Что я хотел бы сделать, это:
- страница клиентских запросов
- лак распознает тайм-аут
- лак доставляет старую страницу клиенту
- лак выбирает новую страницу из бэкэнда и помещает ее в кеш
В моем случае это не сайт, где устаревшая информация является такой большой проблемой, особенно когда речь идет о тайм-ауте кеша от нескольких минут.
Тем не менее, я не хочу наказывать пользователя ждать в очереди и скорее доставить что-то немедленно. Это возможно каким-то образом?
Чтобы проиллюстрировать это, приведем пример вывода команды «Осада 5 минут» на моем сервере, который был настроен для кэширования в течение одной минуты:
HTTP/1.1,200, 1.97, 12710,/,1,2013-06-24 00:21:06
...
HTTP/1.1,200, 1.88, 12710,/,1,2013-06-24 00:21:20
...
HTTP/1.1,200, 1.93, 12710,/,1,2013-06-24 00:22:08
...
HTTP/1.1,200, 1.89, 12710,/,1,2013-06-24 00:22:22
...
HTTP/1.1,200, 1.94, 12710,/,1,2013-06-24 00:23:10
...
HTTP/1.1,200, 1.91, 12709,/,1,2013-06-24 00:23:23
...
HTTP/1.1,200, 1.93, 12710,/,1,2013-06-24 00:24:12
...
Я пропустил сотни запросов, запущенных 0.02
или около того. Но все равно меня беспокоит, что будут пользователи, которым придется ждать почти 2 секунды своего необработанного HTML.
Разве мы не можем сделать лучше здесь?
(Я наткнулся на Varnish send в то время как кеш , это звучало похоже, но не совсем то, что я пытаюсь сделать.)
Решение
Ответ от Шейна Мэддена содержал решение, но я не сразу понял это. Была еще одна деталь, которую я не включил в свой вопрос, потому что я думал, что это не имеет отношения к делу, но на самом деле это так.
Решение CMS, которое я сейчас использую, имеет прослушиватель базы данных лака и, следовательно, имеет возможность уведомлять лак о запрете страниц, содержание которых изменилось. Он отправил PURGE
запрос с некоторым регулярным выражением, чтобы запретить определенные страницы.
Чтобы подвести итог, есть два случая, когда я получил незадачливых пользователей:
- истекает нормальный лак TTL страницы
- бэкэнд-пользователи меняют контент, отправляет запрос на очистку для лака
В обоих случаях у меня «неудачливые» пользователи. Во втором случае это облегчается тем фактом, что бэкэнд-пользователи обычно проверяют страницу после ее изменения; но не обязательно.
Тем не менее, для второго случая я создал решение (да, я понимаю, что этот вопрос начался с поиска ответа для первого случая ... плохо сформулированный вопрос с моей стороны):
Вместо отправки запроса на очистку я использовал предложение Шейна и настроил VCL так, чтобы мой слушатель базы данных лака мог отправить специальный запрос для получения страницы с hash_always_miss
установленным значением true
.
С текущей архитектурой я не могу позволить себе настоящий асинхронный запрос, но с помощью Как сделать асинхронный запрос GET в PHP? Мне удалось создать запрос GET для лака, который не ждет загрузки страницы, но достаточно хорош, чтобы вызвать лак, чтобы извлечь страницу из бэкэнда и кэшировать ее.
Результатом было то, что слушатель базы данных отправил запрос на лакировку, и пока я опрашивал определенную страницу, мои запросы никогда не делались «неудачными», но однажды лак полностью извлек страницу из бэкэнда (это может варьироваться от 300 мс до 2 с). вдруг был там.
Я все еще должен найти решение, как избежать тех же проблем, когда нормальный TTL заканчивается, но я думаю, что решение также точно так, как предлагает Шейн: использование wget для запуска hash_always_miss
, я просто должен быть достаточно умен, чтобы получить список страниц я должен обновить.