2015-11-30 2 views
1

Я использую рамки django и сталкивался с некоторыми проблемами производительности.Совместимость Django с сельдереем

В моем представлении очень тяжелый (который стоит около 2 секунд). И назовем его тяжелым().

Клиент использует ajax для отправки запроса, который перенаправляется на heavy() и ожидает ответа json.

Плохо то, что, думаю, heavy() не является одновременным. Как показано на рисунке ниже, если есть два запроса, перенаправленных на heavy() одновременно, нужно подождать еще один. Другим словом, heavy() является серийным: он не может принять другой запрос перед возвратом из текущего запроса. Наблюдение проверено и проверено на моей локальной машине.

synchronous django

Я пытаюсь сделать функции в views.py одновременно и асинхронный. В идеале, когда есть два запроса, поступающие в heavy(), heavy() должен отбросить задание на какого-то удаленного работника с обратным вызовом и вернуться. Затем heavy() может обрабатывать другой запрос. Когда задача будет выполнена, обратный вызов может отправить результаты обратно клиенту. Логика демонстрируется, как показано ниже:

asynchronous django

Однако есть проблема: если тяжелая() хочет, чтобы обработать другой запрос, он должен вернуться; но если он что-то вернет, структура django отправит клиенту (поддельный) ответ, и клиент может не дождаться другого ответа. Более того, поддельный ответ не содержит правильных данных. Я искал метод stackoverflow и нашел менее полезные советы. Интересно, кто-нибудь пробовал это и знает хороший способ решить эту проблему.

Спасибо,

+1

Какой сервер вы используете? Сервер разработки Django? –

ответ

2

Сначала убедитесь, что «inconcurrency» на самом деле вызваны вашей тяжелой задачей. Если вы используете только один рабочий для django, вы сможете обрабатывать только один запрос за раз, независимо от того, каким он будет. Подумайте о том, что у вас больше рабочих для параллелизма, потому что это повлияет и на короткие запросы.

Для возвращения некоторой информации, когда дело сделано, вы можете сделать это, по крайней мере, два способов:

  • отправка AJAX запросы periodicaly принести статус вашей задачи
  • с использованием SSE или WebSocket подписаться на фактический

Для обоих из них потребуется написать еще код JavaScript для его обработки. Первый из них действительно прост в достижении, во-вторых, вы можете использовать возможности uWSGI, как описано here. Он может быть обработан асинхронно таким образом, независимо от ваших рабочих Джанго (Django будет просто создать соединение и начать задачу в сельдерее, проверки состояния и отправки его клиенту будут обработаны GEvent

+1

Я сам использую опрос. Эта статья, на которую вы ссылаетесь, является обязательным для людей, которые хотели бы работать с Django с помощью websocket. – Louis

0

Чтобы следить за ответом GwynBliedD в:.

сельдерей обычно используется для обработки задач, он имеет очень простую интеграцию по джанго. @ Первое предложение GwynBlieD очень часто реализуется с использованием сельдерея и ферментативного результата.

https://www.reddit.com/r/django/comments/1wx587/how_do_i_return_the_result_of_a_celery_task_to/

Общий рабочий процесс с помощью сельдерея является:

  1. клиента попадет тяжелые()
  2. тяжелых() очередей тяжелой() задачу асинхронен
  3. тяжелых() возвращает будущую задачу идентификатор клиент (просмотр возвращается очень быстро, потому что на самом деле выполнялась небольшая работа)
  4. клиент начинает опрос оконечной точки состояния с помощью задачи ID
  5. Когда задача завершает возврат статуса к клиенту
Смежные вопросы