2009-07-07 10 views
8

Obecnie próbuję wdrożyć prosty serwer HTTP dla pewnego rodzaju comet -technique (długie zapytania XHR). Jak JavaScript jest bardzo surowe o crossdomain wniosków Mam kilka pytań:Zrozumienie mod_proxy i Apache 2 do pisania komet-serwera

  1. Jak rozumieć każdy pracownik apache jest zablokowany podczas wysyłania żądania, więc pisanie „skrypt” jako zwykłej stronie będzie blokować apache, gdy wszystko pracownicy mający prośbę do służby. -> Nie działa!
  2. Wpadłem na pomysł napisania własnego prostego serwera HTTP tylko do obsługi tych długich zapytań. Ten serwer nie powinien być blokowany, aby każdy pracownik mógł obsłużyć wiele żądań w tym samym czasie. Ponieważ moja witryna zawiera również treść/obrazy itp. I mój serwer nie potrzebuje zawartości serwera, uruchomiłem go na innym porcie niż na 80. Problem polega na tym, że nie mogę komunikować się między moim JavaScript dostarczonym przez mój apache i mój serwer-kometę działa na innym porcie, ze względu na niektóre ograniczenia crossdomain. -> Nie działa!
  3. Potem wpadłem na pomysł, aby użyć mod_proxy, aby zmapować mój serwer na nowej poddomenie. Naprawdę nie wiem, jak działa mod_proxy, ale mogę sobie wyobrazić, że wiem, że mają taki sam efekt jak w moim pierwszym podejściu?

Jaki byłby najlepszy sposób na stworzenie tego rodzaju połączenia tego rodzaju klasycznej strony internetowej i tych żądań XHR z długim podziałem? Czy muszę samodzielnie wprowadzić dostarczanie treści na mój serwer?

Odpowiedz

3

Jestem całkiem pewny, że użycie mod_proxy zablokuje pracownika podczas przetwarzania żądania.

Jeśli możesz użyć dwóch adresów IP, istnieje dość łatwe rozwiązanie. Załóżmy, że IP A to 1.1.1.1, a IP B to 2.2.2.2, a powiedzmy, że domena to example.com.

To jak to będzie działać:

-configure Apache nasłuchuje na porcie 80, ale tylko na IP A.

-Start swojej innego serwera na porcie 80, ale tylko na IP B.

- Skonfiguruj żądania XHR, aby znaleźć się w poddomenie domeny, ale z tym samym portem. Tak więc ograniczenia między domenami nie stanowią dla nich przeszkody. Twoja witryna to example.com, a żądania XHR na przykład xhr.example.com.

-configure swojej DNS tak, że example.com postanawia IP A i xhr.example.com postanawia IP B.

-Jesteś zrobić.

To rozwiązanie będzie działać, jeśli masz dwa serwery i każdy ma swój adres IP, i będzie działać również, jeśli masz jeden serwer z 2 adresami IP.

Jeśli nie możesz użyć dwóch adresów IP, mogę mieć inne rozwiązanie, sprawdzam, czy dotyczy to Twojego przypadku.

+0

Jestem zainteresowany pomysł z użyciem tylko jednego adresu IP. – TheHippo

+1

Nie sądzę, że model zabezpieczeń przeglądarki pozwala kodowi załadowanemu z example.com wysłać XHR do xhr.example.com. Musisz grać w gry z document.domain i IFrames, a potem nie jest to przenośne. - http: //www.fettig.net/weblog/2005/11/28/how-to-make-xmlhttprequest-connections-to-another-server-in-your-domain / –

3

To jest trudny problem. Nawet jeśli rozwiążesz problemy z bezpieczeństwem, na które napotykasz, będziesz musiał utrzymywać połączenie TCP otwarte dla każdego klienta, który aktualnie szuka strony internetowej. Nie będzie można utworzyć wątku do obsługi każdego połączenia, a nie będzie można "wybrać" wszystkich połączeń z jednego wątku. Robiąc to wcześniej, mogę powiedzieć, że to nie jest łatwe. Możesz zajrzeć do libevent, które memcached używa do podobnego końca.

Aż do punktu, w którym prawdopodobnie można uniknąć ustawiania długich limitów czasu i umożliwienia Apache posiadania ogromnej liczby pracowników, z których większość będzie bezczynna przez większość czasu. Uważam, że ostrożny wybór i konfiguracja modułu roboczego Apache rozszerzy go na tysiące równoczesnych użytkowników. W pewnym momencie jednak nie będzie już skalować.

Nie wiem, jak wygląda infrastruktura, ale mamy szafy do równoważenia obciążenia w szafach sieciowych zwanych F5. Są to jedna zewnętrzna domena, ale przekierowują ruch do wielu wewnętrznych serwerów na podstawie ich czasów odpowiedzi, plików cookie w nagłówkach żądań itp. Mogą być skonfigurowane do wysyłania żądań określonej ścieżki w domenie wirtualnej do określonego serwera. W ten sposób możesz mieć przykład.com/xhr/foo żądania zmapowane do określonego serwera, aby obsłużyć te żądania komet. Niestety, nie jest to oprogramowanie, ale raczej drogie rozwiązanie sprzętowe.

W każdym razie możesz potrzebować jakiegoś systemu równoważenia obciążenia (lub może go już masz) i być może można go skonfigurować tak, aby radził sobie z tą sytuacją lepiej niż Apache.

Miałem problem lat temu, gdy chciałem, aby klienci korzystający z systemu klient-serwer z zastrzeżonym protokołem binarnym mieli dostęp do naszych serwerów na porcie 80, ponieważ ciągle mieli problemy z zaporami ogniowymi na niestandardowym porcie, który system używany. Potrzebowałem serwera proxy, który działałby na porcie 80 i skierował ruch na serwer Apache lub serwer aplikacji w zależności od kilku pierwszych bajtów tego, co spotkało klienta. Szukałem rozwiązania i nie znalazłem nic, co by pasowało. Zastanawiałem się nad napisaniem modułu Apache, wtyczką do DeleGate, itp., Ale ostatecznie przetoczone przez własną, niestandardową usługę wykrywania treści. To, jak sądzę, najgorszy możliwy scenariusz dla tego, co próbujesz zrobić.

0

Aby odpowiedzieć na konkretne pytanie dotyczące mod-proxy: tak, można skonfigurować mod_proxy do wyświetlania treści generowanych przez serwer (lub usługę), który nie jest dostępny publicznie (tj. Który jest dostępny tylko za pośrednictwem wewnętrznego adresu lub localhost).

Zrobiłem to w środowisku produkcyjnym i działa bardzo, bardzo dobrze. Apache przesyła niektóre żądania do Tomcat za pośrednictwem pracowników AJP, a inne do serwera aplikacji GIS za pośrednictwem mod proxy. Jak inni zwrócili uwagę, bezpieczeństwo cross-site może przestać Pracujesz na subdomeny, ale nie ma powodu, dlaczego nie można wnioski proxy do mydomain.com/application


mówić o swoich specyficznych problem - myślę, że naprawdę ugrzęzłeś patrząc na problem jako "długowieczne prośby" - tzn. zakładając, że kiedy wykonasz jedną z tych żądań, to cały proces musi się skończyć. Wygląda na to, że próbujesz rozwiązać problem z architekturą aplikacji poprzez zmiany w architekturze systemu. W rzeczywistości należy traktować te żądania w tle dokładnie jako takie; i wielowątkowego go:

  • Klient składa wniosek do zdalnego serwisu „wykonać zadanie X z danych A, B i C
  • Usługa odbiera żądanie: przechodzi go na scheduler które wystawia unikalny bilet/token dla żądania.Następnie usługa zwraca ten token klientowi "dzięki, twoje zadanie jest w kolejce działającej pod tokenem Z"
  • Klient następnie zawiesza się na tym tokenie, wyświetla okno "ładowanie/proszę czekać" i konfiguruje Timer odpala powiedzieć, na argumentach, co drugi
  • Kiedy pożary timer, klient sprawia, że ​​kolejny wniosek do zdalnego serwisu „masz wyniki dla mojego zadania, to żeton z
  • ty serwis tle można następnie sprawdź w harmonogramie i prawdopodobnie zwróci pusty dokument "nie, jeszcze nie wykonane" lub wyniki
  • Gdy klient otrzyma wyniki z powrotem, może po prostu wyczyścić licznik i wyświetlić je.

Tak długo, jak dobrze się czujesz z gwintowaniem (co musisz zrobić, jeśli zaznaczyłeś, że patrzysz na pisanie własnego serwera HTTP, nie powinno to być zbyt skomplikowane - na początku http część słuchacz:

  • Harmonogram obiekt - Singleton obiekt, naprawdę, że po prostu owija się „pierwsze weszło, pierwsze wyszło” stos Nowe zadania iść na koniec stosu, zadania można oderwać od początku: po prostu zrobić. upewnij się, że kod do wydania pracy jest bezpieczny dla wątków (mniej masz dwie prace wyciągając tę ​​samą pracę ze stosu).
  • Nici pracownicze mogą być dość proste - uzyskać dostęp do harmonogram, poproś o następną pracę: jeśli istnieje, to praca wysłać wyniki, inaczej spać przez pewien okres, zacznij od nowa.

W ten sposób nigdy nie będziesz blokować Apache dłużej niż to konieczne, ponieważ wszystko, co robisz, to prośby o "do x" lub "daj mi wyniki x". Prawdopodobnie będziesz chciał zbudować kilka funkcji bezpieczeństwa w kilku punktach - takich jak obsługa zadań, które zawiodły, i upewnienie się, że jest czas oczekiwania po stronie klienta, aby nie czekać w nieskończoność.

0

Dla numeru 2: można obejść ograniczenia crossdomain za pomocą JSONP.

0

DwaTrzy alternatywy:

  1. Use nginx. Oznacza to, że uruchamiasz 3 serwery: nginx, Apache i własny serwer.
  2. Uruchom serwer na własnym porcie.
  3. Użyj Apache mod_proxy_http (jako własną sugestię).

Ustaliliśmy mod_proxy_http (Apache 2.2.16) działa buforowania komety aplikacji (Powered by Atmosphere 0.7.1) uruchomione w GlassFish 3.1.1.

Moja aplikacja testu z pełnym źródłem jest tutaj: https://github.com/ceefour/jsfajaxpush