2013-02-28 17 views
8

Mamy bardzo złożoną aplikację Django obsługiwaną obecnie przez apache/mod_wsgi i wdrożoną na wielu instancjach AWS EC2 za systemem równoważenia obciążenia AWS ELB. Aplikacje klienckie wchodzą w interakcję z serwerem przy użyciu AJAX. Okresowo odpytywają również serwer, aby pobrać powiadomienia o aktualizacjach ich stanu. Chcemy usunąć ankietę i zastąpić ją "push" za pomocą gniazd internetowych.Jak zintegrować gniazda internetowe za pomocą django wsgi

Ponieważ dowolne instancje obsługiwać internetowych żądań gniazd od klientów i trzymać tych gniazd internetowych, a ponieważ chcemy zapisywać dane do klientów, którzy nie mogą znajdować się na tej samej instancji, który dostarcza source dane za naciśnięciem, my Potrzebujemy sposobu na przekierowanie danych do odpowiedniej instancji , a następnie z tej instancji do odpowiedniego gniazda sieciowego klienta .

Zdajemy sobie sprawę, że apache/mod_wsgi nie grają dobrze z gniazdami internetowymi i planuje zastąpić te komponenty nginx/gunicorn i korzystać z narzędzia gevent-websocket . Jeśli jednak jeden z kilku procesów roboczych odbiera żądania od klientów w celu ustanowienia gniazda internetowego, a czas życia procesów roboczych jest kontrolowany przez główny proces gunicorn , nie jest jasne, w jaki sposób inne procesy robocze, lub w rzeczywistości procesy nie-gunicorn mogą wysyłać dane do tych gniazd internetowych.

Przypadkiem szczególnym jest ten: Użytkownik, który zgłasza żądanie HTTP, jest skierowany do jednej instancji EC2 (hosta), a pożądanym zachowaniem jest to, że dane są wysyłane do innego użytkownika, który ma otwarte gniazdo internetowe. całkowicie różne wystąpienie. Można łatwo wyobrazić sobie system, w którym komunikatowi brokerowi (na przykład rabbitmq) działającemu na każdej instancji można wysłać wiadomość zawierająca dane do wysłania przez gniazda internetowe do klienta połączonego z tą instancją. Ale w jaki sposób obsługa tych wiadomości może uzyskać dostęp do gniazda sieciowego, które zostało odebrane w procesie roboczym gunicorn? Obiektów sieci wysokiego poziomu w pythonach utworzonych przez gevent-websocket i udostępnionych pracownikowi nie można zaszyfrować (są to instancje metod bez wsparcia dla wytrawiania), więc nie można ich łatwo udostępnić przez proces roboczy do długiego - uruchamianie, proces zewnętrzny.

W rzeczywistości, korzeń to pytanie sprowadza się do tego, jak można gniazd internetowych zainicjowane przez żądań HTTP od klientów i obsługiwanych przez WSGI teleskopowe w serwerach takich jak gunicorn być dostępne przez zewnętrzne procesów? Nie wydaje się, że procesy przetwarzające gunicorn,, które są przeznaczone do obsługi żądań HTTP, powodowałyby odradzanie się długich wątków , aby zawiesić się na gniazdach internetowych i wiadomościach obsługi technicznej od innych procesów wysyłania wiadomości do gniazd internetowych, które mają został dołączony przez te procesy robocze.

Czy ktoś może wyjaśnić, w jaki sposób gniazda sieciowe i żądania HTTP oparte na WSGI mogą współdziałać ze środowiskiem, które opisałem?

Dzięki.

Odpowiedz

0

Nie wydaje się słuszne, że gunicorn procesów roboczych, które są przeznaczone do obsługi żądań HTTP będzie tarło długotrwały wątki powiesić na gniazdach internetowych oraz obsługę wsparcia wiadomości od innych procesów do wysyłania wiadomości do gniazd internetowych zostały przyłączone przez te procesy robocze.

Dlaczego nie? W końcu jest to połączenie długotrwałe. Długotrwały wątek, by zająć się takim połączeniem, wydaje mi się ... całkowicie naturalny.

Często w tych zaistniałych sytuacjach pisanie odbywa się niezależnie od czytania.

Pracownik, który aktualnie obsługuje połączenie z internetem, czekał na przesłanie odpowiedniego komunikatu z serwera komunikacyjnego, a następnie przekazał go dalej do serwera sieciowego.

Możesz również użyć przyjaznych dla geventu kolejek do obsługi przekazywania wiadomości w kodzie, jeśli chcesz.

+0

Jeśli w wyniku obsługi jednego żądania HTTP serwer musi wysłać powiadomienie push w sieci Web, że inny użytkownik połączył się z innym procesem roboczym na tym samym hoście lub na innym hoście, pracownik wysyłający musi umieścić w kolejce wiadomość (gdzieś, ale być może na serwer AMQP, do którego subskrybuje każdy pracownik) i odbierający (ten, który trzyma na websocket od klienta docelowego) musiałby odczytać wiadomość z kolejki i wysłać ją do sieci gniazdo elektryczne. Czy wydaje się to rozsądną architekturą? – eswenson

+0

Nie czułem się komfortowo, używając procesów roboczych do "innej pracy" niż przetwarzania żądania/odpowiedzi, ale wydaje się, że mówisz, że nie ma powodu, dla którego nie mogliby. Dobrze? – eswenson

+0

Cóż, websocket nie wykonuje już prostej obsługi żądania/odpowiedzi, czyż nie? Teraz jest pełnowymiarowym kanałem dupleksowym. Możesz przekazać połączenia sieciowe do oddzielnej puli pracowników, jeśli ci się podoba. Tak, sugerowane przez ciebie wrażenie jest normalnym łukiem. Dla mnie. :) – Ivo

1

Myślę, że dokonałeś poprawnego stwierdzenia, że ​​mod_wsgi + websockets to nieprzyjemna kombinacja.

Znaleźlibyśmy wszystkich pracowników wsgi wychwyconych przez gniazda sieciowe, a próba (masowego) zwiększenia rozmiaru puli pracowniczej prawdopodobnie spowodowałaby dławienie serwera z powodu użycia pamięci i przełączania kontekstu.

Jeśli lubisz trzymać się synchronicznej biblioteki wsgi (w przeciwieństwie do reaktywnego podejścia zaimplementowanego przez gevent, twisted, tornado itp.), Sugerowałbym, żebyś spojrzał na uWSGI jako serwer aplikacji. Najnowsze wersje mogą obsługiwać niektóre adresy URL w stary sposób (np. Twoje istniejące widoki django nadal będą działać tak samo jak poprzednio) i przekierowywać inne adresy URL do obsługi asynchronicznego websocket. To może być względnie gładka ścieżka migracji.

+0

Od tego czasu przełączyliśmy się na model, w którym używamy NGINX jako naszego proxy HTTP i mamy proxy dla gunicorn (django) lub nodejs. Aplikacja nodejs obsługuje nasze gniazda sieciowe. Możemy wkrótce odejść od gunicorn i spróbować uWSGI, ponieważ wierzymy, że wydajność będzie lepsza. To, czy przełączymy obsługę websockets z powrotem na python/django, będzie zależeć od tego, czy naprawdę uważamy, że ma to dużą zaletę. Wygląda na to, że Nodejs dobrze sobie radzi z tymi połączeniami sieciowymi. – eswenson

Powiązane problemy