@MaratFM

Fork запросов в Nginx?

Задача: на входе есть 1 HTTP запрос, нужно проксировать его сразу на 2 сервера: a.com и b.com; в качестве ответа нужно вернуть ответ от a.com, ответа от b.com дожидаться не обязательно.

Мне удалось найти 3 решения:

1) Использовать echo-nginx-module
Проблема этого варианта в том, что модуль все таки будет дожидаться ответа от второго сервера и будет конкатенировать ответ с первым.
location /main {
     echo_location_async /sub1;
     echo_location_async /sub2;
 }
 location /sub1 {
     proxy_pass http://a.com/;
 }
 location /sub2 {
     proxy_pass http://b.com/;
 }


2) Использовать lua и ngx.location.capture_multi
В этом случае больше контроля и можно явно вернуть только результат первого запроса. Но все еще приходится ждать пока второй запрос закончится.
location / {
  content_by_lua_block { 
    res1, res2 = ngx.location.capture_multi{
        { "/sub1" },
        { "/sub2" },
    }
    ngx.say(res1.body)
  }
}
location /sub1 {
    proxy_pass http://a.com/;
}
location /sub2 {
    proxy_pass http://b.com/;
}


3) Использовать lua и создавать легковестный тред через ngx.thread.spawn
Здесь та же проблема что и со вторым, lua модуль будет ждать завершения второго запроса.

Для вариантов с lua может помочь ngx.flush. Если ответ от первого сервера содержит Content-Length заголовок и если вызвать ngx.flush после отправки тела ответа, то теоритически клиент может начать обрабатывать ответ не дожидаясь закрытия соединения.

Известны ли вам другие варианты решения данной проблемы?

P.S. если вам интересно узнать для чего это может понадобиться, отвечу - нужно проксировать запрос на основной сервер и при этом логировать его в отдельном сервисе, логирование не должно тормозить и вообще влиять на основной запрос.
  • Вопрос задан
  • 215 просмотров
Пригласить эксперта
Ответы на вопрос 1
daager
@daager
Что используется на backend'е? Если PHP то можно самой первой строчкой вписать fastcgi_finish_request(). В результате вернется сразу пустой ответ, а скрипт продолжит своё выполнение. Если что-то другое, то можно поискать, есть ли подобные реализации.
P.S. Какого рода логирование? Может есть смысл настроить access_log на серваке, дальше уже работать с ним?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы