Dostępne rozwiązania równoważenia obciążenia dla aplikacji napisanych w Javie praktycznie ograniczają się do kilku modułów do serwera HTTP Apache. Nie, nie twierdzę, że rozwiązanie jest złe! Powiedziałbym wręcz przeciwnie — serwer ten ma ugruntowaną pozycję na rynku, jest stabilny, a co najważniejsze — jest darmowy! Są oczywiście rozwiązania sprzętowe (np. urządzenia oferowane przez loadbalancer.org), jednak, co tu dużo mówić — ich cena jest dosyć zniechęcająca…

Jak to było do tej pory?

Podstawowym modułem serwera Apache obsługującym połączenia na linii Apache — serwer aplikacji był (a w zasadzie nadal jest) moduł mod_proxy (wraz z modułami zależnymi przeznaczonymi dla konkretnego protokołu np. AJP, HTTP). Jego konfiguracja jest naprawdę bardzo prosta. Mając raz utworzony plik konfiguracyjny można go wykorzystać w innych instalacjach zmieniając tylko potrzebne opcje. Dodatkowo, jeżeli skonfiguruje się moduł mod_proxy_balancer (domyślny sposób równoważenia obciążenia w serwerze Apache — pisałem o tym  wcześniej), otrzymujemy możliwość zdefiniowania wielu serwerów aplikacji, jak i zasad równoważenia obciążenia między nimi. Po szczegóły odsyłam do (krótkiej, ale konkretnej) dokumentacji. Dodatkowo w Internecie można znaleźć tony instrukcji w jaki sposób uruchomić load balancer na podstawie serwera Apache na wybranej dystrybucji Linuksa (uruchamia to ktoś na Windowsie?!). Rozwiązanie oparte na mod_proxy i mod_proxy_balancer jest naprawdę dobre, ale głupie. Moduły nie wiedzą nic o stanie serwerów aplikacji poza tym, czy działają :) Na ogół takie postawienie sytuacji powinno wystarczyć. Jednak w przypadku gdybyśmy chcieli obciążać tylko jeden serwer, a drugi traktować jako dodatkową moc obliczeniową wykorzystywaną tylko i wyłącznie w przypadku, gdy pierwszy serwer nie jest w stanie obsłużyć wszystkich zapytań, rozwiązanie oparte na mod_proxy_balancer nie będzie pomocne.

Z pomocą nadchodzi mod_cluster

Od początku listopada tego roku na stronach społeczności JBossa udostępniony został projekt pod kierownictwem Jean-Frederic Clerea o dumnej nazwie mod_cluster. Oprócz niego w projekcie uczestniczą Brian Stansberry oraz Paul Ferraro.  Zadaniem mod_cluster, zupełnie tak jak w przypadku mod_proxy, jest przekierowywanie zapytań z serwera Apache do serwerów aplikacji. W takim razie, czym różnią się te rozwiązania? W odróżnieniu od mod_proxy, w przypadku mod_cluster komunikacja jest dwukierunkowa. Serwer aplikacji dodatkowo nawiązuje połączenie z serwerem Apache. Właśnie to połączenie odpowiada za inteligencję tego rozwiązania. Za jego pomocą przekazywane są informacje z cyklem życia aplikacji, jak również inne informacje potrzebne do zarządzania load balancerem (np. aktualne obciążenie serwera aplikacji). Informacje przesyłane są za pomocą protokołu Mod-Cluster Management Protocol (MCMP), który w rzeczywistości jest zbiorem metod protokołu HTTP. Co ciekawe — nie jest wymagane utworzenie nowego gniazda dla tych połączeń — serwer aplikacji komunikuje się z serwerem Apache na porcie, na którym jest on skonfigurowany! W rzeczywistości mod_cluster nie jest pojedynczym modułem. Jest to raczej zbiór następujących modułów: mod_slotmem, mod_manager, mod_proxy_cluster oraz mod_advertise. Duża część kodu źródłowego jest oparta na aktualnych implementacjach mod_proxy. Co ciekawe, to konfiguracja po stronie serwera aplikacji odpowiedzialna jest za mapowanie odpowiednich adresów do aplikacji. Szczególny wpływ ma na to konfiguracja domeny i ścieżki danej aplikacji na serwerze aplikacji. Dane te są przesyłane za pomocą wiadomości CONFIG do wszystkich load balancerów.  Jeżeli przychodzące do serwera Apache zapytanie dla wybranej domeny i ścieżki zostanie odnalezione wśród wpisów posiadanych przez moduł mod_cluster, zapytanie to zostanie automatycznie przekierowane do wybranego węzła.

Wymagania

Aby móc uruchomić mod_cluster potrzebny jest serwer Apache w wersji powyżej 2.2.8. Niestety aktualna wersja httpd dostępna dla systemu Red Hat / CentOS 5.2 oznaczona jest numerem 2.2.3. Pozostaje skompilować samemu odpowiednie moduły z dostępnego kodu źródłowego, gdy chcemy wykorzystać standardową instalację demona httpd. Należy zwrócić uwagę, że deweloperzy przygotowali odpowiednie paczki dla wielu systemów operacyjnych zawierające całą potrzebną instalację (łącznie z serwerem Apache!). Wszystko jest kompletne, skonfigurowane i gotowe do użytku! Można to lepiej zrobić?

Do uruchomienia mod_cluster potrzebny jest również odpowiedni kontener. W grę wchodzi JBoss Application Server 5.0.0+, Apache Tomcat, oraz JBoss Web 2.1.1+. Niestety nie doszukałem się informacji z jakimi wersjami Apache działa mod_cluster.

Najważniejsze cechy mod_cluster

Rozwiązanie JBossa wprowadza wiele usprawnień wpływających na konfigurację i zarządzanie klastrem. Oto niektóre z nich.

Dynamiczna konfiguracja workerów (a po polsku?)

Do tej pory to load balancer musiał wiedzieć jakie serwery aplikacji wchodzą w skład klastra. Powodowało to potrzebę rekonfiguracji load balancerów przy dodawaniu nowego węzła w klastrze. Od tej pory, przy użyci mod_cluster, to serwery aplikacji będą posiadały informację o dostępnych load balancerach. Informacja ta może być umieszczona na stałe w konfiguracji serwerów aplikacji jako lista lub mogą one zostać wykryte automatycznie przez serwer aplikacji przy użyciu muticastu za pośrednictwem mechanizmu advertise. W środowiskach, w których nie można użyć multicastu (np. VMware) należy skonfigurować ręcznie listę dostępnych load balancerów.

Współczynnik obciążenia obliczany po stronie serwerów aplikacyjnych

Współczynniki rozkładu obciążenia w przypadku mod_proxy_balancer (jak i w starym mod_jk) były umieszczane na stałe w konfiguracji tych modułów. Statyczna konfiguracja mogła doprowadzić do przeciążenia jednego serwera, gdy inne w klastrze nie były obciążone. Oczywiście zależało to od poprawnego zdefiniowania współczynników. W przypadku mod_cluster problem ten został wyeliminowany. Współczynniki są obliczane po stronie serwerów aplikacji a następnie przekazywane do load balancera, który znając współczynniki wszystkich węzłów w klastrze może efektywnie zarządzać zapytaniami w zależności od obciążenia serwerów.

Należy dodać, że rozwiązanie to sugeruje się informacjami otrzymanymi od serwerów — po stronie serwera http nie ma obliczania współczynników!

Pełna kontrola cyklu życia aplikacji

Rozwiązania dostępne obecnie na rynku w postaci modułów serwera Apache nie potrafią poprawnie obsłużyć takich zdarzeń jak wdrożenie, czy usunięcie aplikacji z serwera. Odwołanie się do usuniętej z serwera aplikacji powoduje po prostu wyświetlenie błędu 404. W przypadku mod_cluster błędy te zostały wyeliminowane, ponieważ informacje o cyklu życia aplikacji są przesyłane do load balancera.

Architektura mod_cluster

Architekturę mod_cluster można podzielić na dwie części. Z jednej strony znajdują się usługi uruchomione na serwerze http, z drugiej strony usługi uruchomione na serwerze aplikacji. Po stronie serwera http uruchomiony jest zestaw modułów wspomnianych wcześniej, natomiast po stronie serwera aplikacji uruchomiona jest usługa ModClusterService. Usługa ta odpowiedzialna jest za komunikację z dostępnymi load balancerami. W szczególności dotyczy to informowania ich o stanie serwera i aplikacji na nim uruchomionych. Szczegółowe informacje można znaleźć na stronach wiki projektu.

Wyróżnić można dwa tryby pracy klastra: z klastrowaniem lub bez.

Konfiguracja bez klastrowania

W tym trybie serwery aplikacji nie wymieniają danych między sobą.

Konfiguracja bez klastrowania

Konfiguracja bez klastrowania

Oznacza to, że dwie, te same, aplikacje uruchomione na dwóch serwerach nie będą wiedziały o swoim istnieniu, oraz żadne dane nie będą replikowane do innych serwerów. Klient, po awarii jednego z serwerów i przełączeniu do innego, straci wszystkie dane znajdujące się aktualnie sesji, będzie się musiał również ponownie zalogować. Oczywiście przesyłane są informacje do serwera http odpowiedzialne za rejestrację serwera apliakcji w load balancerze, czy związane z cyklem życia aplikacji. Natomiast współczynnik obciążenia przesyłany przez serwer aplikacji będzie miał wartość obliczaną (lub ustalaną odgórnie) tylko dla tego konkretnego serwera. Współczynnik ten będzie wpływał na działanie całego systemu tak samo jak wartość lbfactor w pliku konfiguracyjnym workers.properties modułu mod_jk.

Konfiguracja z klastrowaniem

W tym trybie serwery aplikacji formułują klaster, a dane są wymieniane między węzłami w klastrze.

Konfiguracja z klastrowaniem

Konfiguracja z klastrowaniem

Wymieniane są również informacje o aktualnym stanie serwerów pomiędzy instancjami. Jedna z usług ModClusterService będzie zawierała komponent HASingleton odpowiedzialny za zbieranie informacji o stanie wszystkich węzłów. Następnie dane te są poddawane analizie, a wyniki w postaci czynnika obciążenia dostarczane są wszystkim węzłom w klastrze oraz dostępnym load balancerom.

Instalacja

Należy skonfigurować odpowiednio serwer Apache i aplikacji. Bardzo dobra dokumentacja instalacji znajduje się na stronach mod_cluster, zarówno jeżeli chodzi o konfigurację serwera Apache jak i serwera aplikacji.

Podsumowanie

Pewnie parę osób zarzuci mi, że jestem przesadnie podekscytowany tym rozwiązaniem. Być może, ale nie ulega żadnej wątpliwości, że mod_cluster zmieni całkowicie podejście do programowych load balancerów. Polecam przyjrzenie się temu projektowi! Według mapy wydań możemy się spodziewać w najbliższym czasie pierwszego, stabilnego wydania mod_cluster, a więc nie ma na co czekać, tylko uruchamiać. W końcu każdy chce mieć stabilny i szybki system. Co? Może nie?

Warto odwiedzić