Python "Сервер задач" - PullRequest
4 голосов
/ 30 апреля 2009

Мой вопрос: какую среду Python я должен использовать для сборки своего сервера?

Примечания:

  • Этот сервер общается по протоколу HTTP со своими клиентами: GET и POST (через pyAMF)
  • Клиенты "отправляют" "задачи" для обработки, а затем, спустя некоторое время, получают связанный "task_result"
  • Отправка и получение могут быть разделены днями - разные HTTP-соединения
  • «Задача» - это кусок XML, описывающий проблему, которую нужно решить, а «task_result» - это кусок XML, описывающий ответ.
  • Когда сервер получает «задачу», он ставит ее в очередь на обработку
  • Сервер управляет этой очередью и, когда задачи попадают в начало, организует их обработку.
  • обработка выполняется длительной (15 минут?) Внешней программой (через подпроцесс), которая передает XML-файл задачи и создает кусок «task_result» XML, который сервер берет и сохраняет (для последующего извлечения клиента ).
  • обслуживает несколько основных HTML-страниц, отображающих очередь и статус обработки (только для администраторов)

Я экспериментировал с twisted.web, используя SQLite в качестве базы данных и потоков для обработки длительных процессов.

Но я не могу не чувствовать, что мне не хватает более простого решения. Я? Если бы вы столкнулись с этим, какую технологию вы бы использовали?

Ответы [ 5 ]

2 голосов
/ 30 апреля 2009

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

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

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

Некоторые популярные реализации Python для очередей сообщений:

1 голос
/ 13 октября 2009

Можете взглянуть на сельдерей

1 голос
/ 30 апреля 2009

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

Встроенные обратные вызовы (слегка документировано здесь: http://twistedmatrix.com/documents/8.2.0/api/twisted.internet.defer.html) обеспечивают средства, позволяющие сделать длинные цепочки отложенных элементов намного более удобочитаемыми (вплоть до того, чтобы выглядеть как прямой код). Отличный пример уменьшения сложности это дает здесь: http://blog.mekk.waw.pl/archives/14-Twisted-inlineCallbacks-and-deferredGenerator.html

Вам не всегда нужно, чтобы ваша массовая обработка хорошо интегрировалась с Twisted. Иногда легче разбить большую часть вашей программы на отдельный, легко тестируемый / настраиваемый / реализуемый инструмент командной строки, и Twisted вызывает этот инструмент в другом процессе. Twisted ProcessProtocol обеспечивает довольно гибкий способ запуска и взаимодействия с внешними вспомогательными программами. Более того, если вы вдруг решите, что хотите облачно приложению, не так уж сложно использовать ProcessProtocol, чтобы просто запустить массовую обработку на удаленном сервере (возможно, случайные экземпляры EC2) через ssh, если вы уже настроили ключи.

1 голос
/ 30 апреля 2009

Я бы предложил следующее. (Так как это то, что мы делаем.)

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

Я использовал модификацию основного цикла «Служить навсегда» в wsgiref, чтобы периодически опрашивать всех детей, чтобы узнать, как у них дела.

Простая база данных SQLite может отслеживать состояние запроса. Даже это может быть излишним, потому что ваши входные данные и результаты XML могут лежать в файловой системе.

Вот и все. Очереди и потоки на самом деле не входят в это. Один длительный внешний процесс слишком сложен для координации. Проще всего, если каждый запрос - это отдельный, дочерний процесс.

Если вы получаете огромные пакеты запросов, вы можете захотеть, чтобы простой губернатор не создавал тысячи детей. Регулятор может быть простой очередью, построенной с использованием списка с append () и pop (). Каждый запрос поступает, но отбираются только те запросы, которые соответствуют определенному пределу «Максимальное количество детей».

0 голосов
/ 30 апреля 2009

Кажется, любой веб-фреймворк Python удовлетворит ваши потребности. Я работаю с подобной системой ежедневно и могу вам сказать, что ваше решение с потоками и SQLite для хранения очередей примерно такое же простое, как и вы.

Если порядок не имеет значения в вашей очереди, то потоки должны быть приемлемыми. Важно убедиться, что вы не создаете условия гонки со своими очередями или, например, не выполняете одновременно два задания одного и того же типа. Если это так, я бы предложил однопоточное приложение, чтобы сделать элементы в очереди один за другим.

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