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

#ajax #jquery #node.js #long-polling

#ajax #jquery #node.js #длительный опрос

Вопрос:

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

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

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

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

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

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

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

Ответ №1:

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

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

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

https://github.com/simonw/dogproxy

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

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

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

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

Комментарии:

1. Спасибо, что четко объяснили, на чем я спотыкался. Необходимость проводить опрос кажется несоответствием в асинхронной философии узла.

2. Ожидаете ли вы увидеть второй запрос (повторную попытку) в инспекторе Chrome? У меня такое же поведение, описанное выше, при повторной попытке через 2 минуты, но нет указаний на то, повторяет ли это клиент или сервер.

3. Эмиль, я не думаю, что сервер вообще способен инициировать повторную попытку на клиенте — как только соединение сбрасывается, клиент должен повторно подключиться сам. Таким образом, он ДОЛЖЕН отображаться в инспекторе Chrome, если вы записываете сетевые события. Однако, если бы повторная попытка выполнялась каким-либо промежуточным прокси, вы бы не увидели ее на клиенте и не имели бы над ней никакого контроля. Обычно не получается заставить клиента ждать завершения работы сервера более пары секунд из-за ненадежного mdeium HTTP и Интернета в целом без состояния.

4. Пол: Это противоречит философии асинхронности. В идеальном асинхронном мире вы бы предоставили серверу URL для отправки ответа вместо ожидания или опроса ответа. К сожалению, в Интернете существует значительная асимметрия между клиентами и серверами, когда дело доходит до «достижимости», поэтому серверу очень сложно перезвонить клиенту (при условии, что javascript даже предоставил механизм для этого). Длительный опрос работает нормально и не требует больших дополнительных затрат. Эти длительные операции должны быть довольно редкими для большинства приложений.