2013-02-28 4 views
8

У нас есть значительно сложное приложение Django, которое в настоящее время обслуживается apache/mod_wsgi и развернуто на нескольких экземплярах AWS EC2 за балансировщиком нагрузки AWS AWS. Клиентские приложения взаимодействуют с сервером с использованием AJAX. Они также периодически опросают сервер для получения уведомлений и обновляют их состояние. Мы хотим удалить опрос и заменить его «push», используя сетевые розетки.Как интегрировать сетевые сокеты с django wsgi

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

Мы понимаем, что апач/mod_wsgi не играют хорошо с веб-сокеты и план, чтобы заменить эти компоненты с Nginx/gunicorn и использовать GEvent-WebSocket работника. Однако, если один из нескольких рабочих процессов получает запросы от клиентов, чтобы установить веб-сокет, а если срок службы рабочих процессов контролируется основным процессом пушки-стрелка , неясно, как другие рабочие обрабатывают, или фактически процессы без пушки могут отправлять данные в эти сетевые сокеты.

Конкретный случай это: Пользователь, который выдает запрос на HTTP является направлен в одну EC2 экземпляра (хост) и желаемое поведение является то, что данные для отправки другого пользователя, который имеет веб-сокет открыт в полностью различных экземпляров. Можно легко представить систему, в которой брокером (например, rabbitmq), запущенным на каждом экземпляре, может быть отправлено сообщение , содержащее данные, которые должны быть отправлены через веб-сокеты, к клиенту, подключенному к этому экземпляру, подключенному . Но как обработчик этих сообщений может получить доступ к веб-сокете, который был получен в рабочем процессе с пушкой? Объекты веб-сокета высокого уровня python, созданные gevent-websocket и , которые доступны для работника, не могут быть маринованными (они являются экземплярами методов без поддержки травления), поэтому их невозможно легко разделить рабочим процессом на некоторое время - внешний, внешний процесс.

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

Может ли кто-нибудь объяснить, как веб-сокеты и HTTP-запрос на основе WSGI могут взаимодействовать с обработчиками в среде, которую я описал?

Спасибо.

ответ

0

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

Почему бы и нет? В конце концов, это длинное соединение. Долговечная нить, которая позаботится о такой связи, показалась бы ... абсолютно естественной для меня.

Часто в этих случайных ситуациях запись обрабатывается отдельно от чтения.

Рабочий, который в настоящее время обрабатывает соединение с веб-соединением, будет ожидать, что соответствующее сообщение спустится с сервера обмена сообщениями, а затем передайте это с помощью websocket.

Вы также можете использовать дружественные к асинхронным очередям gevent для обработки сообщений в коде, если хотите.

+0

Если в результате обработки одного HTTP-запроса серверу необходимо отправить push-уведомление по веб-расписанию, которое другой пользователь подключил к другому рабочему процессу на одном и том же хосте или другом хосте, отправляющий рабочий должен поставить в очередь сообщение (где-то, но, возможно, на сервер AMQP, на который подписаны каждый работник), и получающий работник (тот, кто держит веб-кластер от целевого клиента) должен будет прочитать сообщение из очереди и отправить его по сети разъем. Это похоже на разумную архитектуру? – eswenson

+0

Мне не понравилось использование рабочих процессов для «другой работы», чем обработка запросов/ответов, но вы, кажется, говорите, что нет причин, по которым они не могли. Правильно? – eswenson

+0

Хорошо, что websocket больше не выполняет простую обработку запроса/ответа, не так ли? Теперь это полнодуплексный дуплексный канал. Вы могли бы связать сетевые соединения с отдельными пулами работников, если хотите. Да, то, что вы предложили, похоже на нормальную арку. мне. :) – Ivo

1

Я думаю, вы сделали правильную оценку, что mod_wsgi + websockets - это неприятная комбинация.

Вы обнаружите, что все ваши работники wsgi, запущенные веб-сокетами, и попытка увеличить размер рабочего пула, возможно, захлестнут из-за использования памяти и переключения контекста.

Если вам нравится придерживаться синхронной архитектуры рабочего стола wsgi (в отличие от реактивного подхода, реализованного gevent, twisted, tornado и т. Д.), Я бы предложил изучить uWSGI в качестве сервера приложений. Последние версии могут обрабатывать некоторые URL по-старому (т. Е. Существующие представления django все равно будут работать так же, как и раньше) и маршрутизировать другие URL-адреса в обработчик async-websocket. Это может быть относительно гладкий путь миграции для вас.

+0

С тех пор мы перешли на модель, в которой мы используем NGINX в качестве нашего HTTP-прокси и имеем прокси-сервер для либо пушки (django), либо nodejs. Приложение nodejs обрабатывает наши веб-сокеты. Вскоре мы можем отказаться от пушки и попробовать uWSGI, так как мы считаем, что производительность будет лучше. Переключим ли мы поддержку websockets обратно на python/django или нет, будет зависеть от того, действительно ли мы думаем, что есть много преимуществ для этого. Теперь Nodejs обрабатывает эти подключения к сети. – eswenson