У меня есть приложение в RubyOnRails, проксируемое сервером NGINX, который находится за службой CDN. CDN имеет ограничение: если первый байт ответа не приходит в течение 60 секунд, сервер CDN отвечает:
Error 503 first byte timeout
Проблема в том, что у меня есть некоторые запросы, обработка которых на стороне Rails занимает более 60 секунд. Есть ли способ взломать ответ, отправив несколько байтов до того, как ответ завершит свою обработку? Как?
Редактировать 1:
Я знаю, что 60-е - это долгий срок, и мы думаем, как этого избежать. Тем не менее, мне нужно временное решение, которое позволяет работать с запросами 60-х годов. Даже если я использую Ajax, некоторые вызовы ajax займут более 60 секунд и попадут в ту же проблему. Параметры tcp_nopush или tcp_nodelay не работали, я думаю, это потому, что nginx ожидает ответа приложения rails, чтобы узнать, какие заголовки он должен отправить. Так что, возможно, решение - это то, что мне нужно взломать в цикле запросов / ответов RubyOnRails.
Запрос, занимающий более 60 секунд, - это значительное время. Вы можете просмотреть свою заявку. При такой длительной загрузке страницы из вашего приложения может выйти много посетителей. Вы можете рассмотреть возможность асинхронной загрузки данных, например, с помощью AJAX или веб-сокетов.
Время до первого байта обычно применяется к заголовкам, а не к телу ответа. Клиент должен получать заголовки на ранней стадии. Вы уверены, что это ваш CDN таймаут для запросов? NGinx также будет отключать ваши запросы. Хороший способ проверить это с помощью curl:
curl -I -H "Host: <domain>" http://<ip of proxy>/request/uri
(Используйте реальный IP-адрес вашего прокси, а не IP-адрес CDN)
Опция -I покажет вам заголовки ответов, таким образом вы сможете получить хорошее представление о том, какой код ошибки (если есть) возвращает nginx. Вы также можете увидеть, получаете ли вы заголовки запросов и сколько времени это занимает, поскольку это то, на что ссылается первый байт tcp.
Если вы не получаете заголовки быстро, попробуйте использовать:
http {
tcp_nopush off;
tcp_nodelay on; # force socket to send buffer
}
Если вы получаете сообщение об ошибке тайм-аута шлюза или подобное, попробуйте следующие параметры конфигурации:
http {
keepalive_timeout 300;
proxy_connect_timeout 300;
proxy_read_timeout 300;
proxy_send_timeout 300;
}