ajax, долгий опрос и управление двухминутными повторными попытками

Один из запросов AJAX к моему серверу node.js иногда может занимать более двух минут. Я обнаружил, что когда серверу требуется больше двух минут, клиент повторно отправляет запрос AJAX. Это заставило сервер еще больше увязнуть, так как он запустил второй дорогостоящий процесс.

Чтобы обойти это, я реализовал на сервере решение для длинных опросов. Клиент делает ajax-вызов функции проверки на сервере, которая просто проверяет, завершен ли процесс, и перепроверяет каждые пять секунд и возвращает клиенту, когда это будет сделано.

Однако у меня все еще есть вариация двухминутной задачи. Через две минуты поступает второй вызов проверки AJAX. Затем выполняются обе проверки, и кажется, что только новая будет связываться с клиентом.

Каков наилучший способ решить эту проблему?

  • Есть ли способ настроить или отключить двухминутную повторную отправку ajax?
  • Есть ли лучший способ управлять последующими дублирующими запросами на сервер?
  • Нужно ли мне реализовать тайм-аут на клиенте вместо сервера?

Я использую вызовы jQuery AJAX, сервер node.js в браузере Chrome.

ОБНОВЛЕНИЕ: Из документов node.js "все входящие соединения имеют тайм-аут по умолчанию 2 минуты». Меня по-прежнему интересуют предложения о наилучшей практике кодирования длительных запросов к серверу, когда клиенту не нужно ничего знать, пока сервер не завершит работу.


person Paul Beusterien    schedule 25.10.2011    source источник


Ответы (1)


Чтобы было понятно, что происходит:

  1. Клиент отправляет запрос "сделай это для меня..."
  2. Код узла запускает асинхронную операцию (или несколько связанных вместе)
  3. Проходит две минуты
  4. Время ожидания HTTP-запроса истекло
  5. Клиент повторно отправляет запрос
  6. Сейчас выполняются два запроса
  7. И так до тех пор, пока не будет запущено множество запросов.

Мне кажется, я слышал, что это называется «эффект собачьей кучи». Я не знаю каких-либо стандартных библиотек в node.js или jQuery, которые могли бы вам помочь, хотя кто-то начал работу над кеширующим прокси-сервером, чтобы помочь с этим в случае, когда ответ будет «кэшируемым»:

https://github.com/simonw/dogproxy

Таким образом, вам придется разработать собственную систему, чтобы обойти это.

Существуют разные способы обработки пакетных заданий, и часто это зависит от характера задания.

Что я чаще всего видел для задач, которые занимают много времени, так это то, что API сразу возвращает идентификатор для задания, а затем клиент использует опрос (или длительный опрос), чтобы дождаться завершения задания. Вам понадобится какая-то база данных для хранения состояния (% завершения) и результата задания и позволяет клиенту ждать изменения этого статуса. Это также может позволить вам «отменить» задание, хотя в этом случае код на стороне сервера должен периодически проверять, не было ли оно отменено.

Просто имейте в виду, что где бы вы ни хранили статус задания, он должен быть общим для всех узлов в кластере, если приложение масштабируется или будет масштабироваться позже. Для этого вы можете использовать какую-нибудь высокоскоростную облегченную систему хранения, например memcached или Redis.

person Dobes Vandermeer    schedule 26.10.2011
comment
Спасибо за четкое объяснение того, к чему я споткнулся. Это похоже на несоответствие асинхронной философии узла, когда нужно выполнять опрос. - person Paul Beusterien; 26.10.2011
comment
Ожидаете ли вы увидеть второй запрос (повторную попытку) в Chrome Inspector? У меня такое же поведение, как описано выше, для повторной попытки через 2 минуты, но нет указаний, делает ли это повторная попытка клиента или сервера. - person emilebaizel; 20.11.2012
comment
Эмиль, я не думаю, что сервер обычно способен инициировать повторную попытку на клиенте - после сброса соединения клиент должен снова подключиться. Таким образом, он ДОЛЖЕН отображаться в Chrome Inspector, если вы записываете сетевые события. Однако, если бы повторная попытка выполнялась каким-то промежуточным прокси-сервером, вы бы не увидели ее на клиенте и не имели бы над ней контроля. Как правило, не очень хорошо заставлять клиента ждать завершения операции сервера более пары секунд из-за ненадежного mdeium без сохранения состояния HTTP и Интернета в целом. - person Dobes Vandermeer; 21.11.2012
comment
Пол: Это несовместимо с асинхронной философией. В идеальном асинхронном мире вы бы дали серверу URL-адрес для отправки ответа вместо того, чтобы ждать или опрашивать ответ. К сожалению, между клиентами и серверами в Интернете существует большая асимметрия, когда дело доходит до достижимости, поэтому серверу очень сложно перезвонить клиенту (при условии, что javascript даже предоставил механизм для этого). Длительный опрос работает нормально и не влечет за собой НАМНОГО дополнительных накладных расходов. Эти длительные операции должны быть довольно редкими для большинства приложений. - person Dobes Vandermeer; 21.11.2012