PASOE i Load Balancing

Użytkownicy klasycznego AppServera pamiętają zapewne możliwość dość łatwej implementacji load balancingu, wykorzystującego proces przekierowujący NameServer.
W nowym serwerze aplikacji PASOE nie ma NameServera, nawet proces AdminServera nie jest niezbędny, jak zatem można zrealizować usługę LB?

Aby to osiągnąć musimy wykorzystać istniejące rozwiązania innych firm. Dostępnych jest wiele produktów i ciężko jest wybrać jedną najlepszą opcję load balancingu do wszystkich zastosowań, dla każdego z klientów. Najbardziej znane to: Apache proxy LB, Tomcat LB i Amazon Elastic LB. Skupmy się na dwóch pierwszych rozwiązaniach. Oba wykorzystują popularny serwer Apache.

Apache proxy LB – popularny serwer Apache HTTP działa tutaj jako serwer proxy przekierowujący żądania HTTP do adresu URL, który jest unikalny dla każdej instancji PASOE. Ta metoda nie wymaga konfiguracji po stronie PASOE gdyż całe równoważenie obciążenia wykonywane jest przez serwer Apache.

Wadą tego typu rozwiązania jest to, że serwer Apache nie monitoruje statusu uruchomionych instancji i jeśli któraś z nich ulegnie awarii, serwer kontynuuje próbę wysyłania żądań do niedostępnej instancji i żądania zostają utracone.

Tomcat load balancing – równoważenie obciążenia realizuje tutaj wyznaczona instancja PASOE, która musi nazywać się lb (lub jklb). Jest to jej jedyne zadanie i jeśli instancja ma wdrożone jakiekolwiek aplikacje (np. ROOT) należy je usunąć (undeploy). Poniższy rysunek ilustruje przykładową konfigurację. Oprócz instancji lb można utworzyć opcjonalnie instancję do monitorowania procesu równoważenia. Musi się ona nazywać status (lub jkstatus) i także nie może mieć wdrożonych żadnych aplikacji.

Jednakże, wdrożenie load balancingu jest także możliwe gdy obie w/w instancje są skonfigurowane tylko wirtualnie, tzn. bez ich fizycznego utworzenia (bez komendy tcman create lub pasman create). Jaka jest różnica tego drugiego rozwiązania? Jest nieco łatwiejsze i bardziej nadaje się do demonstracji. Można je także wykorzystać w lokalnej instalacji. W produkcyjnym środowisku lepiej skorzystać z pierwszego sposobu i możliwości jakie dają nam fizyczne instancje PASOE, szczególnie jeśli idzie o bezpieczeństwo.

Tutaj omówię drugi, krótszy sposób. Na początek musimy mieć zainstalowany web serwer  Apache np. 2.4 (w sumie można użyć innego web serwera ale Apache jest najczęściej stosowany ze względu choćby na wspólna konfigurację Apache i Tomcata). Działanie serwera można rozszerzyć poprzez załadowanie odpowiednich modułów, i tak w pliku  conf\httpd.conf odkomentowujemy linie:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so

To powinno wystarczyć, ale dla konkretnej wersji Apache może okazać się, że potrzebny jeszcze jakiś moduł; sprawdzajcie logi jeśli są kłopoty z uruchomieniem.

Teraz tworzymy przykładowe 2 instancje PASOE , między którymi będzie rozkładać się obciążenie. Nazwiemy je node1 i node2.

pasman create -p 8815 -P 8816 -s 8817 -j 8818 %WRKDIR%\node1
pasman create -p 8825 -P 8826 -s 8827 -j 8828 %WRKDIR%\node2

Teraz powiem kilka słów o powyższych instrukcjach. Pasman jest tą samą instrukcją co tcman, ale ma charakter jedynie globalny, tzn. nie ma tej instrukcji w podkatalogu bin dla instancji, przez co łatwiej z niej korzystać w przypadku zarządzania kilkoma instancjami. Stosuje się tutaj parametr -I, po którym podajemy nazwę instancji.

Zwróćcie uwagę, że oprócz 3 portów, podałem jeszcze czwarty oznaczony jako -j dla protokołu AJP13

Jest to binarny protokół, który umożliwia przesyłanie żądań z serwera WWW do serwera aplikacji. Jest on powszechnie stosowany w systemach ze równoważeniem obciążenia; obsługuje również monitorowanie stanu serwera.

Po utworzeniu instancji musimy aktywować protokół AJP13 w pliku conf/server.xml dla każdej instancji.

pasman feature -I node1 AJP13=on
pasman feature -I node2 AJP13=on

Krótka uwaga – zdecydowanie nie zalecam dokonywania zmian w pliku server.xml ręcznie, gdyż łatwo przy tym o błędny wpis i kłopot z prawidłowym uruchomieniem instancji PASOE.

Teraz trzeba skonfigurować obie instancje tak, aby obsługiwały naszą aplikację: ustawić połączenie z bazą, sprawdzić czy są włączone protokoły APSV / REST / WEB / SOAP,
warto wdrożyć (jeśli nie są) manager.war i oemanager.war oraz na koniec jakąś aplikację do testowania. Tych czynności nie będę tutaj opisywał bo była już wcześniej o nich mowa.

Uruchamiamy instancji node1 komendę tcman workers (lub pasman workers -I node1). W podkatalogu utworzy się plik w podkatalogu node1\temp\workers.properties z wygenerowanymi ustawieniami dla load balancingu. Ustawienia te należy traktować raczej jako wzorzec ponieważ wymagają pewnej edycji.

Do tego pliku za chwilę wrócimy; teraz w pliku Apache conf\httpd.conf na samym końcu dodajemy ustawienia:

#workers.properties load balancing config
LoadModule jk_module modules/mod_jk.so
JkWorkersFile C:/Apache24/lbfiles/conf/workers.properties
JkShmFile C:/Apache24/lbfiles/logs/mod_jk.shm
JkLogFile C:/Apache24/lbfiles/logs/mod_jk.log
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
JkMount /* jklb
JkMount /status jkstatus 

Jest tutaj ładowany jeszcze jeden moduł mod_jk.so, jeśli nie ma go w instalacji trzeba pobrać go z sieci i dodać katalogu modules. Wygodnie jest umieścić dane związane z LB w osobnym katalogu, tutaj jest to katalog lbfiles.

W tym katalogu musimy umieścić plik workers.properties odpowiednio skorygowany. Załączam plik z ustawieniami dla niniejszego przykładu.

# List of worker server instances
worker.list=jklb,jkstatus
#
# Global properties
#
# worker.maintain=60
# Common worker properties referenced by individual workers
worker.common.type=ajp13
worker.common.host=PCPTU3
worker.common.socket_timeout=10
worker.common.connect_timeout=10000
worker.common.socket_keepalive=true
worker.common.ping_mode=I
worker.common.ping_timeout=10000
worker.common.retry_interval=100
worker.common.recovery_options=7
# worker.common.connection_ping_interval=10000
# worker.common.fail_on_status=0
# worker.common.max_packet_size=8192
# worker.common.recover_time=60

 

# properties for alias node1 with jvmRoute node1
worker.node1.port=8818
worker.node1.reference=worker.common
worker.node1.lbfactor=1

# properties for alias node2 with jvmRoute node2
worker.node2.port=8828
worker.node2.reference=worker.common
worker.node2.lbfactor=1

# Load balancer directives
worker.jklb.type=lb
#worker.jklb.port=8012
worker.jklb.balance_workers=node1,node2
worker.jklb.method=Request

# Status worker directives
worker.jkstatus.type=status
worker.jkstatus.read_only=False

Omówię niektóre ustawienia: worker.list=jklb,jkstatus – to lista instancji wirtualnych do LB i do monitorowania. Sa również ustawienia dla maszyn z obiema instancjami node1 i node2 (tutaj wszystko znajduje się na jednej maszynie).

worker.jklb.balance_workers=node1,node2 – to lista instancji obsługujących żądania klienckie. Na uwagę zasługują ustawienia: worker.node1.lbfactor=1 oraz worker.node2.lbfactor=1. Określają one udział instancji w procesie obsługi żądań. W tym przypadku podział jest 50%/50%. Jeśli np. node1 ma obsługiwać 2 razy więcej żądań to współczynnik trzeba ustawić 2 razy większy niż node2.

Startujemy obie instancje. Jaki będzie port w adresie URL jeśli mamy kilka instancji PASOE, obsługujących tą samą aplikację? Port w adresie będzie wskazywać na Apache serwer (domyślnie 80), reszta pozostaje bez zmian. Odświeżamy kilka razu adres URL, generując żądania do obsługi.

Jeśli chcemy podejrzeć status LB to podajemy w adresie URL: nazwa_hosta_lb/status, czyli tutaj: localhost/status.

Widać m.in, że obie instancje są aktywne, node2 ma mniej obsłużonych żądań i 2 błędy, co jest związane z moim czasowym wyłączeniem tej instancji (dla testu). Większość oznaczeń jest opisana po najechaniu na nie kursorem. To na razie tyle, jeśli chodzi o Load Balancing.