Назад |
Перейти на главную страницу
Может ли Varnish игнорировать попадание за проход, когда бэкенды больны
Есть ли способ сделать так, чтобы Varnish 4 игнорировал любые объекты в кэше, если все серверные ВМ были помечены как "больные"?
Вот сценарий отказа, который я пытаюсь улучшить:
- Сначала все бэкенды исправны и ведут себя хорошо, возвращая действительный контент со статусом 200. Varnish кэширует эти страницы и обслуживает их в соответствии с их TTL.
- Что-то ломается, допустим, запрос к базе данных занимает больше времени, чем обычно. Бэкэнды начинают медленно возвращать страницы. Затем, в конце концов, запросы начинают полностью истекать по тайм-ауту, и серверные ВМ начинают возвращать «Внутреннюю ошибку сервера» (статус 500).
- Варниш видит эти ответы и отмечает их как несоответствующие с TTL 120 с. дефолт
vcl_backend_response
. - Наконец, срабатывают проверки работоспособности, и Varnish отмечает, что все серверы работают как надо.
- Теперь, когда поступает больше запросов, Varnish видит в кэше объект «хит-за-проход» и решает, что ему нужно выполнить внутреннюю выборку. За исключением того, что все серверные ВМ не работают, что приводит к ошибке 503 «Не удалось получить серверную ВМ».
Эти 503 ответа продолжаются до 2 минут, в зависимости от времени первого не кэшируемого ответа (помеченного как «хит за проход») и когда все серверные ВМ помечаются как «больные». - После истечения срока действия объектов «попадание за проход» из кеша (120 с) Varnish снова начинает обрабатывать эти запросы как обычные попадания и обслуживает кешированные страницы с 200 состояниями в льготном режиме (согласно дефолт
vcl_hit
- "if (obj.ttl + obj.grace > 0) ....
)
Один из способов обхода, который я придумал, - это сократить TTL для объектов «попадание за проход», если они пришли из ответа со статусом 500:
sub vcl_backend_response {
if (beresp.ttl <= 0s && beresp.status == 500) {
set beresp.ttl = 10s;
set beresp.uncacheable = true;
# return inside this if statement to allow builtin vcl_backend_response to run
return (deliver);
}
}
Другие возможности - это настройка интервала и пороговых значений проверок работоспособности или разработка более качественной проверки работоспособности.
Но помимо этого, есть способ явно сказать Varnish: «Да, у вас есть пропуск, но посмотрите - все бэкенды больны! Не беспокойтесь, переключитесь в режим отсрочки».
Если вы хотите такого поведения, вам следует избегать создания объектов с пропуском, когда вы получаете 500 ответов от бэкэнда.
Предположим, что (1) вы всегда запрашиваете один и тот же кешируемый URL / объект X; и (2) объект X в настоящее время хранится в хранилище Varnish с TTL 1 час и периодом отсрочки 24 часа. Теперь предположим следующую временную шкалу:
- t = 0: некоторые клиенты запрашивают X в Varnish. Объект уже кэширован и свежий, поэтому Varnish возвращает его клиенту. Бэкэнд-запросов нет.
- t = 1: бэкэнд не работает, и с этого момента он отвечает 500 на все запросы.
- t = 3601: некоторые клиенты запрашивают X в Varnish. Объект кэшируется, но останавливается, поэтому Varnish возвращает его клиенту и запускает фоновый запрос серверной части для обновления кэшированного объекта X.
- t = 3602: фоновый бэкэнд-запрос получает ответ 500. Объект «попадание за проход» сохраняется с TTL 120 с. Этот объект перезаписывает застрявший объект X.
- t = 3603: некоторые клиенты запрашивают X в Varnish. Обнаружен объект «хит за прохождение», и выполняется внутренний запрос. На клиентскую сторону отправляется ответ 500.
- t = 4000: некоторые клиенты запрашивают X в Varnish. Объект X больше не находится в кеше, и некоторое время назад серверная часть была отмечена как больная. На клиентскую сторону будет отправлен ответ 503: Varnish не может связаться с серверной частью (он помечен как больной), а Varnish не может вернуть льготный контент (он был перезаписан объектом «Hit-for-Pass» на t = 3602).
Решением здесь было бы избегать создания объектов «хит за проход», когда вы получаете 500 ответов от бэкэнда. Вместо этого просто откажитесь от запроса. Таким образом, при t = 3603 и t = 4000 вы отправите остановленную копию объекта на клиентскую сторону.