Mix Python Twisted с многопроцессорной обработкой?
Мне нужно написать прокси-программу в Python, рабочий поток очень похож на веб-прокси. Программа находится между клиентом и сервером, запросами ввода, отправленными клиентом на сервер, обрабатывает запрос, а затем отправляет его на исходный сервер. Конечно, используемый протокол - это частный протокол, использующий TCP.
Чтобы свести к минимуму усилия, я хочу использовать Python Twisted для обработки запроса (часть действует как сервер) и повторной отправки (часть действует как клиент).
Чтобы максимально повысить производительность, я хочу использовать многопроцессорную обработку python (потоки имеют ограничение GIL), чтобы разделить программу на три части (процессы). Первый процесс запускается Twisted для получения запросов, отправки запроса в очередь и немедленного возврата к исходному клиенту. Второй процесс принимает запрос из очереди, обрабатывает запрос дальше и помещает его в другую очередь. Третий процесс принимает запрос из второй очереди и отправляет его на исходный сервер.
Я был новым поклонником Python Twisted, я знаю, что это событие, я также слышал, что лучше не смешивать Twisted с потоковой обработкой или многопроцессорностью. Поэтому я не знаю, подходит ли этот способ или есть более элегантный способ, просто используя Twisted?
Ответы
Ответ 1
Twisted имеет свой собственный управляемый событиями способ выполнения подпроцессов, который (по моему скромному, но правильному мнению) лучше, чем модуль multiprocessing
. Ядро API spawnProcess, но такие инструменты, как ampoule, обеспечивают надводные надстройки более высокого уровня.
Если вы используете spawnProcess
, вы сможете обрабатывать выходные данные из подпроцессов так же, как и с любым другим событием в Twisted; если вы используете multiprocessing
, вам нужно будет разработать собственный способ получения очереди из подпроцесса в Twisted mainloop, так как обычный callFromThread
API, который может использовать поток, не будет работать из другого процесса. В зависимости от того, как вы это называете, он либо попытается рассолить реактор, либо просто использовать другой нерабочий реактор в подпроцессе; в любом случае это потеряет ваш звонок навсегда.
Ответ 2
ampoule
- это первое, что я думаю при чтении вашего вопроса.
Это простая реализация пула процессов, которая использует протокол AMP для связи. Вы можете использовать функцию deferToAMPProcess
, она очень проста в использовании.
Ответ 3
Вы можете попробовать что-то вроде техники совместной многозадачности, как там описано http://us.pycon.org/2010/conference/schedule/event/73/. Это похоже на технику, как глиф, и стоит попробовать.
Вы можете попытаться использовать ZeroMQ с Twisted, но это действительно сложно и экспериментально:)