Смешать Python Twisted с многопроцессорностью?

Мне нужно написать прокси-подобную программу на Python, рабочий процесс очень похож на веб-прокси. Программа находится между клиентом и сервером, принимает запросы, отправленные клиентом на сервер, обрабатывает запрос, а затем отправляет его на исходный сервер. Конечно, используемый протокол является частным протоколом, использующим TCP.

Чтобы свести к минимуму усилия, я хочу использовать Python Twisted для обработки получения запроса (часть действует как сервер) и повторной отправки (часть действует как клиент).

Чтобы добиться максимальной производительности, я хочу использовать многопроцессорность Python (многопоточность имеет ограничение GIL), чтобы разделить программу на три части (процессы). Первый процесс запускает Twisted для получения запросов, помещения запроса в очередь и немедленного возврата успеха исходному клиенту. Второй процесс берет запрос из очереди, обрабатывает запрос дальше и помещает его в другую очередь. 3-й процесс берет запрос из 2-й очереди и отправляет его на исходный сервер.

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

3 ответа

Twisted имеет свой собственный управляемый событиями способ запуска подпроцессов, который (по моему скромному, но правильному мнению) лучше, чем multiprocessing модуль. Основным API является spawnProcess, но такие инструменты, как ампула, предоставляют надстройки более высокого уровня.

Если вы используете spawnProcess вы сможете обрабатывать вывод из подпроцессов так же, как и любое другое событие в Twisted; если вы используете multiprocessing вам нужно будет разработать свой собственный способ на основе очереди для получения вывода из подпроцесса в Twisted mainloop, так как обычный callFromThread API, который может использовать поток, не будет работать из другого процесса. В зависимости от того, как вы это называете, он либо попытается протравить реактор, либо просто использует другой нерабочий реактор в подпроцессе; в любом случае он потеряет ваш звонок навсегда.

ampoule это первое, что я думаю, когда читаю твой вопрос.

Это простая реализация пула процессов, которая использует протокол AMP для связи. Вы можете использовать deferToAMPProcess Функция очень проста в использовании.

Вы можете попробовать что-то вроде техники кооперативной многозадачности, как описано там http://us.pycon.org/2010/conference/schedule/event/73/. Это похоже на технику, как сказал Глиф, и стоит попробовать.

Вы можете попробовать использовать ZeroMQ с Twisted, но пока это действительно сложно и экспериментально:)

Другие вопросы по тегам