У меня есть установка с Apache2, nginx и Varnish над ними.Varnish получает запрос, определяет, для чего он предназначен (статический идет в nginx, динамический идет в Apache), получает ответ от внутреннего и кэширует его при необходимости.
Помимо прочего, Apache генерирует миниатюры.Он создает эскизы с использованием определенной логики и довольно дорог для процессора.Таким образом, Apache сохраняет большой палец на диск для того, чтобы в следующий раз запрос на эту миниатюру был получен, Varnish мог перенаправить его напрямую на nginx.
И вот проблема: Varnish не имеет возможности проверитьесли файл существует где-то в файловой системе, и поэтому он не знает, можно ли использовать бэкэнд nginx или Apache должен сначала создать миниатюру.
Обходной путь, который я сейчас выбрал, довольно прост, но уродлив:
- Varnish получает запрос на миниатюру;
- Varnish отправляет запрос на nginx;
- Если nginx не может найти файл миниатюр, он отвечает с ошибкой 404 и Varnish перенаправляет запрос наApache.
Хотя этот алгоритм кажется простым, на самом деле это не так.В конфигурационном файле VCL необходима следующая реализация:
- В
vcl_recv
всегда предполагается, что миниатюра существует, и весь запрос должен быть перенаправлен на nginx , если он не запрашивается с какого-либо специального хоста ; - В
vcl_fetch
перехватить состояние HTTP объекта, и если оно равно 404, а ресурс является миниатюрой, чем перезаписать хост на специальный, и перезапустить процесс:
VCL:
if( obj.status == 404 ) {
if(req.url ~ "^thumb/") {
set req.http.host = "thumb_generator.site.com";
set req.url = regsub(req.url, "/thumb/(filename)", "thumb_gen.php?filename=\1");
restart;
}
}
Может быть, есть более эффективные способы решения этой проблемы?Я знаю, что Varnish поддерживает C в VCL, может быть, лучше проверить существование файла с помощью C-кода?