Можно ли настроить Varnish на использование второго сервера для какого-либо ресурса, если он получит ошибку 404 с основного сервера?

Это было бы идеальным решением для меня, так как мне нужно передать некоторый сгенерированный контент в веб-браузеры. Мой план состоит в том, чтобы генерировать контент по запросу и сохранять его для следующего раза. Я не хочу, чтобы браузеры каждый раз вызывали мою службу (которая генерирует контент). Я хочу, чтобы они переходили непосредственно к «кэшированному» ресурсу, если он доступен, и вызывали службу только в том случае, если это не так. Поэтому я бы поставил Varinsh перед сервером A, на котором запущена служба, и сервером B, на котором хранятся ранее сгенерированные версии контента. Если он получит запрос на ресурс, который не был закэширован, он попробует сервер B. Получив ответ 404, он запросит тот же ресурс с сервера A.

Можно ли настроить Varnish таким образом с помощью VCL? Если нет, есть ли такое решение, о котором вы знаете?

P.S. Я не хочу отправлять 302 переадресации в браузер, плюс у меня нет контроля над сервером B, чтобы заставить его отправлять такие переадресации вместо 404


person Paweł Sokołowski    schedule 01.12.2010    source источник


Ответы (2)


Это вполне возможно в Varnish. Убедитесь, что в vcl_fetch (и, возможно, в vcl_error) вы проверяете код состояния возврата (например, проверяете статус > 400), выполняете перезагрузку в случае сбоя и в vcl_recv выбираете другой бэкенд, если req.restarts > 0. Например:

backend serverA {
   .host="192.168.0.1";
   .port = "80";
}

backend serverB {
   .host = "192.168.0.2";
   .port = "80";
}

sub vcl_recv {
   if (req.restarts == 0) {
       set req.backend = serverB;
   } else {
       set req.backend = serverA;
   }
}

sub vcl_fetch {
    if (obj.status >= 400 && req.restarts == 0) {
        restart;
    }
}

sub vcl_error {
   if (req.restarts == 0) {
       restart;
   }
}

Но это звучит так, как будто вы заново изобретаете концепцию кэш-сервера. А Varnish — отличный кеш-сервер. Почему бы не иметь один фоновый сервер (serverA) и кэшировать сгенерированные объекты Varnish? Вы можете настроить сложные правила, и вы получите срок действия (кэша), управление очисткой и производительность бесплатно! :)

person ivy    schedule 03.12.2010
comment
Большое спасибо. Похоже, это поможет. Я попробую и вернусь с другим комментарием. - person Paweł Sokołowski; 03.12.2010
comment
А что касается вашего вопроса - мой больной ум придумал этот коварный план, потому что сервер хранения (serverB) на самом деле является Amazon S3 - решением для хранения данных, которое прозрачно масштабируется без дополнительных усилий, и объем генерируемого контента будет значительным. Я не могу позволить себе беспокоиться о том, достаточно ли места для кэша на сервере Varnish, нужен ли ему еще один диск или нет. Имеет ли это смысл? - person Paweł Sokołowski; 03.12.2010
comment
Ваш план может подойти для вашего случая. Однако я бы не рекомендовал его. В реальной жизни требования к кэшированию чего-либо начинаются с простого (мне нужно кэшировать только простые страницы, срок их действия, вероятно, никогда не истекает, всем пользователям предоставляется один и тот же контент, и производительность не является проблемой), и у вас возникает соблазн решить их с помощью вашего дома. заварной «простой» раствор. Через некоторое время требования меняются, и ваше решение становится более продвинутым. Затем вы обнаружите, что кэширование на самом деле сложно настроить и управлять им, и вам захотелось выбрать более стандартную настройку. Подумайте, как это относится к вам... - person ivy; 05.12.2010
comment
Спасибо, я буду осторожен :) Я ценю преимущества WebCache и намерен максимально использовать его стандартные функции, просто добавив за ним дополнительное решение для хранения. - person Paweł Sokołowski; 06.12.2010

В этом примере лак попробуй найти на 6 серверах, если не найдешь, покажи последний msg.

# cat /etc/varnish/default.vcl 
backend serverA {
   .host="10.42.4.104";
   .port = "80";
}

backend serverB {
   .host = "10.42.4.102";
   .port = "80";
}

backend serverC {
   .host = "10.42.4.103";
   .port = "80";
}

backend serverD {
   .host = "10.42.4.101";
   .port = "80";
}

backend serverE {
   .host = "10.42.4.105";
   .port = "80";
}

backend serverF {
   .host = "10.42.4.106";
   .port = "80";
}




sub vcl_recv {
   if (req.restarts == 0) {
       set req.backend = serverA;
   } elseif (req.restarts == 1){
       set req.backend = serverB;
   } elseif (req.restarts == 2){
       set req.backend = serverC;
   } elseif (req.restarts == 3){
       set req.backend = serverD;
   } elseif (req.restarts == 4){
       set req.backend = serverE;
   } else {
       set req.backend = serverF;
   }
}


sub vcl_fetch {
    if (beresp.status >= 400 && req.restarts == 0) {
        return(restart);
    }
    if (beresp.status >= 400 && req.restarts == 1) {
        return(restart);
    }
    if (beresp.status >= 400 && req.restarts == 2) {
        return(restart);
    }
    if (beresp.status >= 400 && req.restarts == 3) {
        return(restart);
    }
    if (beresp.status >= 400 && req.restarts == 4) {
        return(restart);
    }
}

sub vcl_error {
   if (req.restarts == 0) {
       return(restart);
   }
   if (req.restarts == 1) {
       return(restart);
   }
   if (req.restarts == 2) {
       return(restart);
   }
   if (req.restarts == 3) {
       return(restart);
   }
   if (req.restarts == 4) {
       return(restart);
   }

}
person Franco Giovanolli    schedule 20.01.2015