Отправляйте фиктивные данные во время длительного процесса, чтобы Varnish не достигал timeout first_byte_timeout

Я работаю над приложением PHP за Varnish Cache. Системные администраторы хотели бы, чтобы значение first_byte_timeout было относительно низким. Однако в одном конкретном уголке приложения мне нужен длительный процесс PHP (загружается большой файл данных, и все это занимает минуту или две).

Проблема в том, что first_byte_timeout срабатывает задолго до завершения процесса. Естественно, процесс все еще завершается, но Varnish возвращает 503, потому что данные не были отправлены. Для пользователя это выглядит так, как будто что-то пошло не так, и если есть какая-то обратная связь о том, что что-то действительно идет не так, пользователь никогда этого не увидит.

Что я должен делать?

В худшем случае я делаю большой рефакторинг, чтобы процесс мог выполняться в отдельных процессах за кулисами, но это будет много работы.

Можно ли отправить некоторые фиктивные данные через PHP, чтобы Varnish держал соединение открытым?

Однако в этом решении есть сложность: в конце длительного процесса PHP выполняет перенаправление (на другую страницу, где он дает обратную связь пользователю о том, как все прошло). Со всеми вещами, которые я пробовал, это перенаправление завершится ошибкой, если php уже отправил заголовки HTTP, поэтому какие фиктивные данные, которые я отправляю, могут быть фиктивными заголовками? Или что-то, что не заставит PHP думать, что заголовки уже отправлены.

Есть ли способ настроить специальные исключения для Varnish, чтобы только на этом одном экране он ждал дольше, чем глобальный first_byte_timeout?

(Я новичок в Varnish, поэтому, если я упустил какую-то важную информацию, сообщите мне об этом. Спасибо.)


person Jachin    schedule 09.01.2012    source источник


Ответы (1)


Воспользуйтесь быстрым решением и сэкономьте время на разработку: измените параметр first_byte_timeout для этого запроса только в Varnish. Например.:

sub vcl_miss {
  if ( req.url ~ "your/special/url" ) {
    set bereq.first_byte_timeout = 5m;
  }
}
person ivy    schedule 09.01.2012
comment
Здесь есть две проблемы: Переменные bereq.* доступны только в vcl_pass, vcl_miss и vcl_pipe. И req.http.url должен быть req.url. - person Insyte; 10.01.2012
comment
Спасибо. Я исправил это выше. Определение логики в vcl_miss имеет смысл и работает. Альтернативой может быть определение другого бэкенда с более длинным first_byte_timeout и использование его из vcl_recv. - person ivy; 10.01.2012