Как обрабатывать длинные AJAX-запросы - отправьте ответ, но продолжайте работать - PullRequest
3 голосов
/ 08 декабря 2011

Мы отправляем наборы инструкций из браузера в многоуровневое веб-приложение с использованием jquery-ajax.Первый компонент (компонент A, написанный на C #) проверяет и сохраняет инструкции в базе данных, а затем вызывает второй компонент (компонент B, написанный на Java и также вызываемый через HTTP), который обрабатывает инструкции после извлечения их из того же самогобаза данных.Клиент браузера просто опрашивает таблицу rdbms через компонент A после отправки задания, поэтому он эффективно отключается после отправки запроса и не ждет ответа от компонента A.

Каков наилучший способ дляпромежуточный уровень (компонент A) для возврата клиенту сообщения об успешном выполнении, подтверждающего успешную отправку задачи, но затем все еще выполняющего запрос к обработчику задачи (компонент B) и освобождающего все его ресурсы?Возврат ответа - это последнее действие для страницы, поэтому мы должны сделать что-то в другом потоке, прежде чем отправить его обратно в браузер.

Еще один вариант, который мы рассмотрели, - это произойти в компоненте B, гдеОбработчик задач отправляет немедленный ответ на средний уровень, подтверждая запрос, но затем продолжает работать в фоновом режиме.Единственная разница будет в том, где мы создадим дополнительный поток для выполнения работы.

Есть какие-нибудь хорошие идеи о том, как справиться с этим?

Ответы [ 2 ]

2 голосов
/ 08 декабря 2011

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

Лучшее решение, которого следует избегать, - это любая доступная среда фоновых задач.Их преимущество заключается в том, что они будут следовать шаблону очереди производителя / потребителя и будут выполнять все отслеживание для вас через отдельный процесс демона, работающий в фоновом режиме.Но тогда недостатком здесь является то, что процесс-демон все еще будет уязвим.

Еще один вариант - интегрировать службу очередей или обмена сообщениями, такую ​​как Rabbit MQ .Это не только масштабирует, но и имеет очень хорошую реализацию, доступную на разных языках.

1 голос
/ 08 декабря 2011

Что мы сделали в таких ситуациях:

  • Набор команд отправки браузером для компонента A
  • Компонент А проверяет набор инструкций
  • Компонент Команда сохранения, установленная в БД под новым идентификатором «отслеживания» STATUS=PENDING
  • Компонент делает запрос к компоненту B для выполнения работы
  • «Потоки» находятся в компоненте B:
    • Компонент B запускает фоновый поток для выполнения работы, первым делом фоновый поток выполняет обновление статуса «ID отслеживания» до STATUS=RUNNING
    • Основной поток компонента B возвращается к успеху для компонента A
  • Компонент A получает сообщение «успешно запущено» от компонента B, поэтому возвращает свое собственное сообщение «успешно запущено» обратно в браузер вместе с «идентификатором отслеживания». На этом этапе компонент A выполняется с запросом, все ресурсы компонента A свободны.
  • Браузер может выполнять различные вызовы компонента А для проверки статуса «идентификатора отслеживания» в БД
  • Между тем фоновая «нить» компонента B все еще выполняет свою работу, возможно, записывая прогресс по «идентификатору отслеживания»
  • Компонент B завершает работу, обновляет статус «ID отслеживания» в БД, STATUS=OK или STATUS=ERROR и отдает все ресурсы.

Преимущество всего этого в том, что с точки зрения вашего приложения не нужно ждать завершения работы. Фактическая работа выполняется «фоновым» потоком, как если бы вы запускали ее с nohup dothework & в оболочке. Ключ использует БД для мониторинга состояния «идентификационного номера».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...