2012-04-23 15 views
5

Utrzymuję aplikację internetową, która wyrasta z pojedynczego serwera VPS. Architektura składa się z dużej liczby małych użytkowników, każdy z własną subdomeną. Użytkownicy nie wchodzą w interakcje. Load oznacza, że ​​muszę przenieść niektórych użytkowników i wszystkich nowych użytkowników do innej instalacji aplikacji internetowej na oddzielnym serwerze.Skalowanie poziome: routing generowanych przez użytkownika poddomen między serwerami

Obecnie każda poddomena użytkownika przypada na ten sam serwer wirtualny, w którym pojedynczy front kontroler PHP wyświetla odpowiednią treść na podstawie nazwy hosta. Pojedynczy rekord DNS z wildcard dla * .mydomain.com wskazuje na bieżący serwer.

Jaki jest mój najlepszy sposób na przekierowanie różnych poddomen do różnych serwerów?

Myślami:

  • nowej domeny najwyższego poziomu dla każdego serwera. user.s1.mydomain.com, user.s2.mydomain.com itd. (informacje nieeleganckie i informacje o wyciekach)
  • Uruchom mój własny serwer DNS, aby kierować użytkowników między serwerami (dodatkowy punkt awarii, nieznana technologia)
  • A centralny kontroler frontowy/układ równoważący odwrotnie - przesyła wszystkie żądania do odpowiedniego serwera (dodatkowy punkt awarii, potencjalnie ograniczone połączenia).
+1

Czy treść generowana przez użytkownika dla każdej subdomeny znajduje się w bazie danych, czy też przesyła własne dane do systemu plików na serwerze? – drew010

+0

@ rys010 Treści użytkownika są przechowywane zarówno w bazie danych, jak iw systemie plików. Ponieważ użytkownicy nie wchodzą w interakcje, mogę dowolnie konfigurować wiele instancji bazy danych ... problem polega tylko na kierowaniu zapytań do strony. Przypuszczam, że oddzielenie serwerów db + web byłoby kolejnym możliwym sposobem skalowania, ale ostatecznie będę musiał podzielić serwer WWW i będę potrzebował rozwiązania – mappu

+1

To właśnie wymyśliłem. Najbardziej skłaniam się ku DNS, ale to oznacza, że ​​będziesz potrzebował rekordu A dla każdej subdomeny lub niestandardowego rozwiązania DNS, które może przesyłać zapytanie do twojej aplikacji, aby określić, który adres IP będzie używany dla danej poddomeny.Możesz mieć lepsze wyniki pytając o to na ServerFault teraz, gdy o tym myślę. – drew010

Odpowiedz

4

W tym momencie w wyskalowaniu aplikacji wybrałbym centralę przedni load balancer. Nginx powinien obsługiwać wszystkie obciążenia, które są obsługiwane dynamicznie przez jeden serwer. Mamy nginx jako front end dla sześciu serwerów dynamicznych i jednego serwera treści statycznych, a na nginxie nie ma żadnych wąskich gardeł.

W swoim punkcie skalowania, skonfiguruj nginx do obsługi całej zawartości statycznej i dynamicznej zawartości odwrotnego proxy do tak wielu pól, jak to konieczne. Konfiguracja dla prostego towarzysza proxy jest blisko:

upstream upstream_regular_backend { 
    fair; 
    server 10.0.0.1:80; 
    server 10.0.0.2:80; 
} 

server { 
    listen 0.0.0.0:80; 
    server_name example.com; 
    proxy_set_header Host $host; 
    proxy_set_header X-Real-IP $remote_addr; 
    location/{ 
     proxy_pass http://upstream_regular_backend; 
    } 
} 

Dla obsługujących zawartość statyczną i przechodząc z powrotem całą resztę, coś jak:

server { 
    listen 0.0.0.0:80; 
    server_name example.com; 
    proxy_set_header Host $host; 
    proxy_set_header X-Real-IP $remote_addr; 
    index index.php; 
    root /some/dir/: 
    location ~ \.php { 
     proxy_pass http://upstream_regular_backend; 
    } 
} 

Naturalnie, jeśli nie używasz PHP, dostosować konfigurację odpowiednio.

W definicji upstream "fair;" będzie ładować backendy w oparciu o czas odpowiedzi. Dla motywów buforowania możesz użyć "ip_hash;" zamiast tego, ponieważ wyśle ​​żądania od klienta zawsze na tym samym serwerze.

Nasza konfiguracja znajduje się nieco dalej. Posiadamy równoważniki obciążenia nginx, które proxy pośredniczą w pamięci podręcznej lakierów, co z kolei oznacza serwery treści dynamicznych.

Jeśli obawiasz się, że nginx jest pojedynczym punktem awarii, skonfiguruj serwer pomocniczy gotowy do przejęcia IP frontendu w przypadku niepowodzenia.

+0

Dziękuję za odpowiedź - wydaje się, że działa dobrze, o ile nginx może oszczędzić otwarte połączenia, a ip_hash (brakujący kawałek układanki) oszczędza mnie przed ponownymarchitekturowaniem aplikacji, aby nie dbać o to, na który serwer przychodzi każde żądanie. Czy masz moduł równoważenia obciążenia nginx, który przerwie połączenie SSL? – mappu

+0

W przypadku Nginx kończymy SSL, ale nie w opisanym przeze mnie setupie. –

+0

Jeśli chodzi o limity połączeń, z tego, co pamiętam, jedynym limitem, jaki osiągnęliśmy, była liczba otwartych deskryptorów plików. Zmodyfikuj plik nginx init.d i pozwól mu podnieść ulimit -n do tylu, ile potrzeba. Poza tym ruch routingu nginx ma doskonałą wydajność. –

Powiązane problemy