Re: Проблема: upstream buffer is too small

Maxim Dounin mdounin на mdounin.ru
Вт Сен 28 16:55:40 MSD 2010


Hello!

On Tue, Sep 28, 2010 at 12:35:45PM +0400, Илья Винокуров wrote:

> 
> > Без сторонних модулей должна сработать какая-то такая схема с 
> > двойным проксированием:
> > <!--#include virtual="/precache/..." wait="yes" -->
> > location /precache/ {
> > proxy_pass http://localhost/realcache/;
> > proxy_method HEAD;
> > proxy_pass_request_body off;
> > proxy_pass_request_headers off;
> > }
> > location /realcache/ {
> > proxy_pass ...service...;
> > proxy_cache ...
> > }
> > Детали:
> > - В подзапросе из ssi метод при проксировании ставится в HEAD, 
> > чтобы тела ответа с той стороны не присылали.
> > - При втором проксировании с proxy_cache кеш сам поменяет запрос 
> > на GET и закеширует результат.
> > Как вариант - опять же с двойным проксированием, но проксировать 
> > на сервис, и при втором проксировании добавлять X-Accel-Redirect 
> > на реальный бекенд.  Это наверное несколько прямее чем 
> > Maxim Dounin
> 
> Здравствуйте, Максим!
> Не работает такая схема :(
> По этой схеме nginx в локейшн /realcache/ пробрасывает метод запроса HEAD.

Да, так и должно быть.

> Не хватает директивы proxy_set_method.

В /realcache/ должен приходить метод HEAD (это достигается через 
proxy_method HEAD в location /precache/), а на реальный сервис 
уйдёт уже GET - заменит cache в location /realcache/.

Проверил в песочнице - всё работает:

        listen 127.0.0.1:8080;

        location / {
            ssi on;
        }

        location /precache/ {
            proxy_pass http://127.0.0.1:8080/realcache/;
            proxy_method HEAD;
            proxy_pass_request_headers off;
            proxy_pass_request_body off;
        }

        location /realcache/ {
            proxy_pass http://mdounin.ru/;
            proxy_cache one;
            proxy_cache_valid 200 1d;
        }

Запрашиваем /test.html, он содержит ssi вида:

before ssi
<!--#include virtual="/precache/" wait="yes" -->
after ssi

Результат запроса к "сервису" замечательно ложится в кеш, при этом 
в ответе не фигурирует.

> Сделал файлик precache.html, в котором прописал
> <!--#include virtual="/realcache/..." wait="yes" -->
> А потом
>  location /precache/ {
>  proxy_pass http://localhost/precache.html;
>  proxy_method HEAD;
>  proxy_pass_request_body off;
>  proxy_pass_request_headers off;
>  }
>  location /realcache/ {
>  proxy_pass ...service...;
>  proxy_cache ...
>  }
> 
> Так оно тоже не работает - nginx на такие запросы не генерирует тело ответа.

А вот это совсем непонятно как вообще могло бы работать.

> 
> Смотрю в сторону ngx_http_sub_module, так там тоже все не гладко:
> Штатное не понимает регулярку, а без регулярки оно никуда не годится, вот если бы там были директивы:
> sub_filter_start    # Сигнатура, с которой начать вырезать
> sub_filter_stop     # Сигнатура, на какой закончить вырезать
> sub_filter_replace  # Что вставить взамен
> 
> То я свой прекешер обрамил бы длинными символьными последовательностями и затем вырезал бы результат из страницы...

Проще за 15 минут написать модуль, который будет отрезать тело 
ответа у нужного подзапроса целиком.  Ну или взять какой нибудь 
существующий, e.g. bytes фильтр должен справиться.

Maxim Dounin



Подробная информация о списке рассылки nginx-ru