poniedziałek, 14 kwietnia 2014

Konfiguracja klastra Tomcat 7 na praktycznym przykładzie z wykorzystaniem VirtualBox’a

W poniższym artykule zaprezentuję jak skonfigurować klaster opary na serwerze aplikacyjnym Apache Tomcat 7. Aby nadać całości lepszego „smaku” postanowiłem oprzeć swoje rozwiązanie na VirtualBox’ie tak, aby każda maszyna wirtualna symulowała jedną, niezależną maszynę sprzętową. Poniższy schemat sieciowy przedstawia poszczególne części klastra.
Rys. 1 Schemat sieciowy klastra.

Klaster… klaster… klaster… w ogóle co to takiego? I po co to właściwie? Według Wikipedii klastrem komputerowym nazywamy grupę połączonych jednostek komputerowych, które współpracują ze sobą w celu udostępnienia zintegrowanego środowiska pracy. Bazując na definicji z Wikipedii klastrem w tym konkretnym przykładzie można nazwać wiele instancji serwera www, które tworzą jeden wspólny rozproszony serwer www. Uff… definicja już za mną, a teraz druga część pytania, po co to?! Otóż uruchamiając aplikację www na jednym serwerze musimy się liczyć z kilkoma dość poważnymi zagrożeniami. Jeden serwer www po prostu może sobie nie poradzić z odbieraniem i przetwarzaniem dość dużej ilości żądań. Kolejnym przykładem zagrożenia może być fizyczna awaria maszyny. Jeśli serwer przestanie działać, aplikacja natychmiast stanie się niedostępna. Dzięki zastosowaniu klastra wymienione problemy nie mają prawa zaistnieć. Nadesłane żądania będą rozkładana na poszczególne węzły klastra, a w przypadku awarii jednego z węzłów ruch zostanie przekierowany na inny węzeł. Dość gadania… bierzmy się do pracy!

Konfiguracja VirtualBox'a

Pierwszym krokiem jest utworzenie wirtualnej maszyny oraz zainstalowanie na niej systemu operacyjnego Ubuntu 13.10 wersji 32 bitowej. Następnie należy wykonać dwie pełne kopie utworzonej maszyny wirtualnej. Przed uruchomieniem poszczególnych maszyn wirtualnych trzeba ponadto skonfigurować sieć w VirtualBox'ie. Czynność ta dzieli się na dwie części. Pierwsza część dotyczy sprawdzenia globalnych ustawień sieciowych. Musimy się upewnić czy wirtualna sieć VirtualBox Host-Only Ethernet Adapter posiada adres IP: 192.168.56.1 oraz maskę podsieci: 255.255.255.0.
File > Preferences... > Network > Host-only Networks > Ikonka śrubokrętu 

Rys. 2 Globalne ustawienia wirtualnej sieci.

Drugą czynnością jaką należy wykonać jest włączenie dla każdej maszyny wirtualnej dodatkowej karty sieciowej w trybie Host-only Adapter.
Prawym przyciskiem myszy na wybranej maszynie wirtualnej > Settings... > Network > Adapter 2 

Rys. 3 Ustawienia sieciowe aktywnej maszyny wirtualnej.

Pamiętajmy aby Promiscuous Mode było ustawiony na Allow All.

Konfiguracja Apache HTTP Serwer

Nareszcie możemy uruchomić naszą pierwszą maszynę wirtualną i przystąpić do konfiguracji serwera www Apache. Generalnie serwer będzie spełniał dwie funkcje:
  1. Równoważenie obciążenia – przekazywanie żądań do mniej zajętych instancji serwera Tomcat.
  2. Przełączanie po awarii – wykrywanie uszkodzonego węzła i przełączenie ruchu na inną instancję serwera Tomcat.
Pierwszym krokiem jaki należy wykonać jest edycja pliku systemowego /etc/hosts. Plik ten przechowuje adresy IP powiązane z nazwami hostów.
sudo gedit /etc/hosts
Zmieniamy jego treść na:
127.0.0.1 localhost
192.168.56.2 apache
Kolejnym plikiem, który należy zedytować jest plik /etc/hostname.
sudo gedit /etc/hostname
Zmieniamy jego treść na:
apache
Następnym krokiem w konfiguracji systemu jest edycja pliku /etc/network/interfaces. Plik ten przechowuje ustawienia interfejsów sieciowych. Zmieniamy jego domyślną treść na:
auto eth1
allow-hotplug eth1
iface eth1 inet static
address 192.168.56.2 
netmask 255.255.255.0
gateway 192.168.56.1
broadcast 192.168.56.255
Po tych czynnościach możemy zrestartować maszynę wirtualną.

Nareszcie możemy przejść do instalacji serwera www Apache. Proces ten rozpoczynamy wpisując w konsoli następującą komendę:
sudo apt-get install apache2
Postępujemy zgodnie z zaleceniami instalatora. Poprawność instalacji możemy przetestować wpisując w oknie przeglądarki internetowej adres http://localhost. Jeśli naszym oczom ukaże się poniższa treść strony to znak, że serwer www Apache został poprawnie zainstalowany.

Rys. 4 Domyślna strona html serwera Apache.

Sama instalacja serwera Apache to niestety nie wszystko. Domyślna konfiguracja nie zawiera włączonych wszystkich wymaganych modułów. Aby włączyć niezbędne modułu należy wprowadzić poniższe komendy:
sudo a2enmod proxy
sudo a2enmod proxy_ajp
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests
sudo service apache2 restart
Gdy wszystkie moduły zostały poprawnie aktywowane następnym krokiem jest edycja pliku proxy.conf w katalogu /etc/apache2/mods-enabled. Plik ten zawiera szczegółowe ustawienia modułu mod_proxy, dzięki któremu nasz serwer Apache będzie działał jako load balancer przed instancjami serwera Tomcat. Zmieniamy domyślną treść pliku na:
<IfModule mod_proxy.c>
    ProxyRequests Off
    ProxyVia Off
    ProxyPreserveHost On
    
    ProxyPass /examples balancer://cluster/examples
    
    <Proxy balancer://cluster stickysession=JSESSIONID|jsessionid nofailover=Off scolonpathdelim=On>
        BalancerMember ajp://192.168.56.3:8009 min=10 max=100 route=tc1 loadfactor=1
        BalancerMember ajp://192.168.56.4:8009 min=20 max=200 route=tc2 loadfactor=1
        Order Deny,Allow
        Allow from all
    </Proxy>

     <Location /balancer-manager>
        SetHandler balancer-manager
        Order Deny,Allow
        Allow from all
    </Location>
</IfModule>
Po tych czynnościach pozostaje nam jeszcze restart serwera Apache.
sudo service apache2 restart 
Powyższa konfiguracja będzie równoważyć ruch dla zasobu /examples. Warto tutaj wspomnieć, że obciążenie będzie rozkładane równomiernie na dwie instancje Tomcata'a do czasu gdy serwer utworzy dla klienta sesję i wyśle mu znacznik JSESSIONID. Po tym czasie moduł mod_proxy_balancer będzie kierował każde żądanie tego klienta do tej samej instancji Tomcat'a.

Konfiguracja Apache Tomcat 7

Tak jak w przypadku maszyny wirtualnej z serwerem Apache pierwszym krokiem jakim należy wykonać tuż po uruchomieniu świeżego Ubuntu jest konfiguracja nazwy hosta i interfejsów sieciowych. Konfiguracja będzie przebiegała identycznie jak w sekcji wyżej. Pierwszym krokiem jaki należy wykonać jest edycja pliku systemowego /etc/hosts dla dwóch nowych maszyn wirtualnych.
sudo gedit /etc/hosts
Zmieniamy jego treść na:
127.0.0.1 localhost
192.168.56.3 tomcat-a
Natomiast dla drugiej maszyny wirtualnej na:
127.0.0.1 localhost
192.168.56.4 tomcat-b
Kolejnym plikiem, który należy zedytować jest plik /etc/hostname.
sudo gedit /etc/hostname
Zmieniamy jego treść na:
tomcat-a
Natomiast dla drugiej maszyny wirtualnej na:
tomcat-b
Następnym krokiem w konfiguracji systemów jest edycja pliku /etc/network/interfaces. Zmieniamy jego domyślną treść na:
auto eth1
allow-hotplug eth1
iface eth1 inet static
address 192.168.56.3
netmask 255.255.255.0
gateway 192.168.56.1
broadcast 192.168.56.255
Natomiast dla drugiej maszyny wirtualnej na:
auto eth1
allow-hotplug eth1
iface eth1 inet static
address 192.168.56.4
netmask 255.255.255.0
gateway 192.168.56.1
broadcast 192.168.56.255
Po tych czynnościach możemy zrestartować maszyny wirtualne.

Instalacja serwera Apache Tomcat 7 polega na jego pobraniu z oficjalnej strony http://tomcat.apache.org/download-70.cgi oraz rozpakowaniu w wybranym przez nas folderze. Przed uruchomieniem serwera należy upewnić się czy nasz system operacyjny posiada poprawnie zainstalowane środowisko uruchomieniowe Javy. Jeśli pobieranie serwera dobiegło ku końcowi możemy go rozpakować wpisując następującą komendę:
sudo tar -zxvf apache-tomcat-7.0.53.tar.gz
Przed uruchomieniem serwera należy zedytować dwa wpisy w pliku server.xml, który znajdujący się w katalogu apache-tomcat-7.0.53/conf. Czynność tą należy wykonać dla dwóch maszyn wirtualnych. Dla pierwszej maszyny wirtualnej wpisy powinny wyglądać następująco:
...
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
...
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tc1">
...
Natomiast dla drugiej maszyny wirtualnej:
...
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
...
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tc2">
...
UWAGA! parametr jvmRoute musi być unikatowy dla każdego z węzłów klastra.

Po tych czynnościach nie pozostaje nam nic innego jak uruchomienie serwerów Tomcat odpalając skrypt startup.sh.
sudo ./apache-tomcat-7.0.53/bin/startup.sh
Jeśli wszystko przebiegło poprawnie wpisując w oknie przeglądarki adres http://localhost:8080 powinniśmy otrzymać domyślną stronę startową serwera Tomcat.
Rys. 5 Domyślna strona startowa serwera Apache Tomcat 7.

Load Balancer Manager & Examples

Nadszedł czas aby przetestować nasz klaster. Serwer Apache udostępnia Load Balancer Manager, dzięki któremu możemy weryfikować status poszczególnych węzłów klastra. Jeśli wszystko zadziałało poprawnie powinniśmy otrzymać następujące rezultaty wpisują adresy http://192.168.56.2/balancer-manager oraz http://192.168.56.2/examples/ w pasek przeglądarki.
Rys. 6 Balancer Manager.
Rys. 7 Zasób /examples

Automatyzacja testów przy użyciu Selenium Grid i Selenium WebDriver (cześć 1)

WSTĘP


W obecnym czasie coraz częściej spotykamy się z takimi pojęciami jak testy funkcjonalne oraz testy regresyjne. Każda aplikacja webowa z biegiem czasu zyskuje coraz to nowsze funkcjonalności, które wymagają od testerów ciągłej kontroli. Testerzy chcąc usprawnić swoje działania, sięgają po narzędzia służące do automatyzacji testów. Jednym z nich jest Selenium. Jest to darmowy zestaw narzędzi służący do automatycznego testowania aplikacji webowych. Posiada on wiele zalet, lecz jego największym atutem jest współpraca z wieloma językami programowania i frameworkami do testowania. Selenium składa się z trzech części, które można używać niezależnie:

  • Selenium IDE (wtyczka do Firefoksa) - pozwala nagrywać i odtwarzać interakcje użytkownika z przeglądarką,

  • Selenium RC (tzw. Selenium 1) - umożliwia pisanie oraz uruchamianie testów na dowolnej przeglądarce,

  • Selenium + WebDriver (tzw. Selenium 2) - jest efektem połączenia Selenium oraz bibliotek WebDrivera.


W pierwszej części tego artykułu przybliżę narzędzie Selenium Grid oraz przedstawię jak go uruchomić.



SELENIUM GRID


Jest to narzędzie służące do organizacji przebiegu testów dla Selenium RC oraz WebDriver. Swoją popularność zawdzięcza posiadającym możliwością, które minimalizują czas wykonywania testów poprzez równoległe testowanie oraz dystrybucje ich na komputery podłączone do siatki. Umożliwia zarządzanie wieloma środowiskami przy pomocy jednego punktu centralnego dzięki czemu możemy uruchamiać testy w dużej ilości kombinacji (przeglądarek i systemów).

Graficzna reprezentacja możliwości Selenium Grid


KONFIGURACJA ŚRODOWISKA DLA SELENIUM GRID

 

Pierwszym etapem w drodze do uruchomienia Selenium Grid jest sprawdzenie czy posiadamy niezbędne oprogramowanie, a w szczególności:

  • Zainstalowane środowisko Javy na komputerze (Java JDK/Java JRE). Jeśli go nie posiadamy wtedy należy pobrać jego aktualną wersje ze strony Oracle,

  • Paczkę z biblioteką Selenium Server, którą można pobrać ze strony Selenium.

 

URUCHOMIENIE SELENIUM GRID

 

Jako pierwsze uruchamiamy Hub Selenium Grid, czyli nasz punkt centralny, który będzie zarządzał gdzie maja zostać otwarte testy. Otwieramy konsole poleceń i przechodzimy do miejsca gdzie znajduje się nasz plik z biblioteką Selenium Server. Następnie uruchamiamy nasz hub poleceniem
Cyfry znajdujące się na białym tle oznaczają wersję biblioteki, którą udało się nam pobrać, w moim przypadku jest to wersja 2.41.0.  

java -jar selenium-server-standalone-2.41.0.jar -role hub
 
Od momentu wykonania polecenia wystartował nasz Hub Selenium Grid na domyślnym porcie 4444. W sytuacji gdy chcemy uruchomić go na wybranym przez nas porcie wtedy do naszego polecenia musimy dodać parametr -port xxxxStatus naszego Huba możemy sprawdzić wpisując w przeglądarce adres http://localhost:4444/grid/console. Pod tym adresem są przedstawiane wszystkie serwery podłączone do naszego Huba, jednak w obecnej chwili na stronie wyświetlają się nam jedynie jego ustawienia, ponieważ nie podłączyliśmy jeszcze żadnego serwera.

Ostatnim krokiem podczas uruchamiania naszego Selenium Grid będzie podłączenie serwera Selenium (węzła) do istniejącego już Huba. Bez wzgledu na to czy chcemy uruchomic siatke z funkcjami WebDriver, funkcjami Selenium 1 RC lub obiema jednocześnie, używamy tej samej biblioteki Selenium Server, aby dodać węzły. Chcąc dodać węzeł do naszego Huba, otwieramy konsole poleceń, przechodzimy do naszego pliku z biblioteką i wpisujemy komendę
java -jar selenium-server-standalone-2.41.0.jar -role node  -hub http://localhost:4444/grid/register

W wyniku wykonanego polecenia podłączyliśmy serwer do naszego Huba na domyślnym porcie 5555. Teraz po odświeżeniu widoku Huba w przeglądarce powinniśmy ujrzeć nasz nowo dodany serwer.


Domyślnie zostało uruchomionych 11 przeglądarek, lecz gdy użyjemy parametru -browser mozemy sami sprecyzować  przeglądarki, ktore nas interesują podczas naszych testow, a domyślne przeglądarki będą wtedy ignorowane np.
 
java -jar selenium-server-standalone-2.41.0.jar -role node -hub http://localhost:4444/grid/register -port 6666 -browser browserName=firefox,maxInstances=3,platform=LINUX

  
W wyniku tej operacji uruchomiliśmy 3 przeglądarki Firefox na platformie Linux. Dzięki niektórym parametrom możemy sprecyzować ilość odpalanych instancji (-maxInstances) lub określić wersję danej przeglądarki (-version).

Mam nadzieje że przybliżyłem wam narzędzie Selenium oraz to jak w łatwy sposób możemy skonfigurować i uruchomić Selenium Grid. W kolejnym artykule będę kontynuował temat automatyzacji testów oraz przedstawię możliwości Selenium WebDriver. : )

 



niedziela, 13 kwietnia 2014

Garbage collector

KRÓTKI WSTĘP

Niniejszy a artykuł będzie na temat GC(Garbage collection) na przykładzie języka Java. Zaczniemy od podstaw powoli zagłębiając się we wnętrzności naszego śmieciarza oraz pamięci na której on działa. GC wysŧepuje w wielu językach programowania, między innymi: Smalltalk, Python, Ruby, Java, C# czy D(tak, jest to język programowania :)

POJĘCIA

Wszystkie zagadnienia będą omawiane pod kątem GC. Na początek aby rozluźnić atmosferę humorystyczny obrazek :)

Collection of garbage
Garbage Collection

STACK   

Inaczej stos, przechowuje prymitywne typy, referencje do obiektów oraz metod. Czas życia zmiennych jest określony poprzez zasięg deklaracji zmiennej, czyli np. zmienna lokalna w metodzie, lub w pętli. Jeśli np. metoda zakończy swoje działanie, zmienna zadeklarowana w jej obrębie zostanie usunięta ze stosu. Stack występuje dla każdego wątku(domyślnie aplikacja działa na jednym).

HEAP

Inaczej kopiec lub sterta, w jego obrębie są przechowywane obiekty.

Zakładam iż czytelnik ma podstawową wiedzę na temat relacji pomiędzy STACK-HEAP, jeśli nie to dopowiem w uproszczeniu, że stos przechowuje referencję do obiektów znajdujących się na kopcu. Natomiast dla osób bardziej wtajemniczonych polecam link, który ładnie obrazuje tę zależność :)

JVM(Java Virtual Machine)

Słowo "new" rezerwuje pamięć na kopcu(heap). Jeśli brakuje pamięci, JVM za pomocą GB próbuje zrobić miejsce dla nowego obiektu(o ile GC wcześniej się o to sam nie postarał), jeśli się to nie uda zostanie rzucony wyjątek OutOfMemoryException i JVM zakończy swoje działanie.

GC(Garbage collection)

Jest mechanizmem do odzyskiwania pamięci która nie jest już wykorzystywana. GC jest uruchamiany automatycznie, i posiada kilka zaimplementowanych algorytmów odśmiecania, które zostaną opisane poniżej.

MODEL PAMIĘCI

Rys. 1 Szczegółowy model pamięci.



Poniżej po krótce co przechowują główne bloki pamięci:

Method area structure:
  • klasy, kod metod oraz konstruktory
  • zmienne które są potrzebne w runtime
Native area structure:
  • Program counter - adres instrukcji które są obecnie wykonywane, jeśli metoda jest natywna to brak wartości
  • Stack thread - zmienne lokalne, referencje
  • Stack native - wspiera natywne metody
Heap jest podzielony na kilka fragmentów zwanych "generations", tak jak to widać na rysunku nr 1. Jeśli obiekt przetrwa GC, który rozpocznie sprzątanie, zostanie przeniesiony do kolejnego 'generation'. Fragment pamięci zwany Old generation nie jest zbyt często odwiedzany przez GC, ponieważ obiekty które przechowuje udowodniły iż są potrzebne w aplikacji.

Gdy obiekt zostaje stworzony poprzez 'new' trafia do Eden space. Jeśli przetrwa najazd GC, zostanie promowany do Survivor Space, natomiast jeśli tutaj utrzyma się wystarczająco długo zostanie nominowany do Tenured Generation(na powyższym obrazku opisana jako Old Generation)


Prosty kawałek kodu, na przykładzie którego pokażę co gdzie wyląduje.
public class Main {
    public static void main(String[] args) {
        try {
            String hello = "Hello ";
            StringBuilder stringBuilder = new StringBuilder(hello);
            stringBuilder.append(" DISCOVET IT");
            System.out.println(stringBuilder.toString());
        }catch (Exception e){
            System.out.println("Unexpected error");
        }
    }
}

Rys. 2 Tabela, która pokazuje umiejscowienie zmiennych, obiektów oraz klas

UWAGA

Permanent Generation, inaczej PermGen, nie podlega pod GC. Zawiera niezmienne obiekty, definicje klas oraz stałe typu String. W związku z tym należy uważać gdy dynamicznie zaczniemy wytwarzać klasy lub stałe.

PermGen w Java 8 ma zostać zastąpiony na rzecz Metaspace, ale ciekawskich odsyłam do sieci:)

BŁĘDY KTÓRYCH NIE CHCESZ POPRAWIAĆ

Memory Leaks / OutOfMemory

Zachodzi wtedy gdy przechowujemy referencję do obiektów których już nie używamy, uniemożliwiając tym samym usunięcie ich przez GC.

Rodzaje OutOfMemoryError, które najczęściej występują:

  • Exception in thread "main" java.lang.OutOfMemoryError: Java heap space(pamięć dla obiektu nie może być zarezerwowana)
  • Exception in thread "main" java.lang.OutOfMemoryError: PermGen  space(klasa i metody nie mogą zostać załadowane do PermGen)
  • Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit(zachodzi gdy rozmiar tablicy jest większy nić rozmiar kopca)
  • Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded(The concurrent collector will throw an OutOfMemoryError if too much time is being spent in garbage collection: if more than 98% of the total time is spent in garbage collection and less than 2% of the heap is recovered, an OutOfMemoryError will be thrown.) - fragment z dokumentacji, nie tłumaczyłem bo niektóre rzeczy lepiej wyglądają w oryginale :)

Poniżej prosty przykład kodu i screen z programu VisualVM obrazujący jak w tym przypadku pracuje GC. JVM została uruchomiona z parametrem -Xmx10M.

public class Main {
    public static void main(String[] args) throws IOException {
        System.out.println("HELLO MEMORY LEAK");

        while (true){
            for (int i = 0; i < 100000; i++) {
                new MySimpleObject("GIVE ME MEMORY LEAK "+i);
            }
        }
    }
}
 

 Niestety powyższy kod nie spowoduje wycieku pamięci, ponieważ GC bardzo sprawnie wykonuje swoją pracę, co jest widoczne na poniższym rysunku.


Rys. 3 Działanie GC dla powyższego kodu

A teraz szybkie zadanie, popraw powyższy kod w taki sposób, aby na konsoli zobaczyć poniższy wynik:

    Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded

StackOverflowError

Gdy jest wywoływana pewna metoda, jej zmienne lokalne wędrują na samą górę stosu. Niestety obszar stosu jest ograniczony. W przypadku gdy metoda rekurencyjna, zbyt wiele razy zostanie wywołana, może dojść do sytuacji gdy nie będzie miejsca dla jej zmiennych. Wtedy zobaczymy błąd o którym mowa. Poznałeś przyczynę błędu, więc za pewne wiesz jak stworzyć taki błąd? Pomyśl.... myśl... myśl... myśl... myśl... myśl... myśl... myśl... myśl. Jeśli ci się nie udało to podpowiem, po prostu wywołaj metodę rekurencyjną i nie przerywaj jej działania:)

Algorytmy GC

Reference Counting

Najprostsza metoda odśmiecania. Alokowany obiekty posiada dodatkowe pole, które przechowuje liczbę odwołań. Na starcie pole to ustawiane jest na 1. Podczas tworzenia obiektów lub ich usuwania, licznik jest zwiększany, lub zmniejszany. Wyzerowanie licznika oznacza, iż przydzielona pamięć może zostać zwolniona.

Concurrent GC

Inaczej mark-and-sweep, podstawowy algorytm GC. Każdy obiekt otrzymuje tzw. markbit mówiący czy obiekt jest potrzebny czy nie(0, 1). Pamięć nie jest odzyskiwana gdy stwierdzi się, że obiekt jest już niepotrzebny, lecz gdy zostanie przekroczona pamięć pewnego progu. Program jest wtedy zatrzymywany i uruchamiana jest faza odśmiecania. Wyróżniamy dwie fazy:
  • Mark - GC oznacza używane obiekty(markbit = 1)
  • Sweep  - GC usuwa obiekty, których markbit wynosi 0 oraz rejestruje nowe, czyli te które nie są już potrzebne.

 

Copying Collector

Heap jest dzielony na dwa równe obszary. Pierwszy zawiera aktywne dane, drugi nieaktywne. Gdy aktywna połowa staje się pełna, wątek programu zostaje zatrzymany, żywe obiekty zostają przekopiowane do nieaktywnej części pamięci, a następnie aktywna część pamięci zostaje wyczyszczona. W kolejnej iteracji działanie jest takie samo, tylko nieaktywna część pamięci stała się aktywną, a aktywna nieaktywną. (mam nadzieję, że nie zaciemniłem :)


Mark-Compact Collector

Wszystkie wątki aplikacji zostają zatrzymane. Wyróżniamy dwie fazy:
  • Mark - zaczynając od korzenia, każda referencja jest odwiedzana i znakowana
  • Compact - cały kopiec jest skanowany, wszystkie nieoznaczone referencje są zbierane i ustawiane na sam szczyt kopca z flagą która mówi że powinny zostać usunięte

Generational Collector

Najnowszy algorytm odśmiecania, występuje od Java 6, w wersji Java 7 został zoptymalizowany. Heap jest podzielony na tzw. "generations". Obiekty są tworzone w "young generations". Gdy pamięć jest potrzebna, następuje proces nominacji obiektów do wyższych stref lub jeśli są niepotrzebne, są gromadzone przez GC. "Old generation" używa algorytmu Mark-Compact do odśmiecania.

(Gdy znajdę chwilę, podlinkuje tutaj artykuł w którym porównam wszystkie algorytmy)

JVM – ustawienia pamięci

Specyfikacja dostarcza wielu komend za pomocą których możemy dostosować naszą JVM. Do wyboru mamy 3 przyrostki G, M, K(kilobajty). Poniżej wymienię najbardziej powszechne, zostały one również oznaczone na rys. 1.

-Xmx1024M (Maximum heap), parametr na starcie nie ustawi od razu takiej ilości pamięci, stanie się to dopiero wtedy gdy zajdzie potrzeba alokacji pamięci, która wykracza poza obecne zasoby, wcześniej zanim to nastąpi zostanie uruchomiony GC, który będzie próbował zrobić porządek.
-Xms512M (pamięć jaką zostanie zainicjalizowany heap)
-XX:MaxPermSize=1024M
-XX:PermSize=512M
-XX:+HeapDumpOnOutOfMemoryError  (stan sterty przed wystąpieniem błędu zostanie zrzucony do pliku)
-XX:HeapDumpPath=C:\sciezka_do_pliku 

-XX:ThreadStackSize=512M (nie należy go używać, jeśli napotkamy błąd StackOverflowExceptions, należy poprawić kod)

W jaki sposób ustawić powyższe parametry? Pokażę na przykładzie środowiska Intellij, natomiast jeśli komuś to nie wystarczy to odsyłam do google z frazą " how to set JVM arguments"

Rys. 4 ustawienia parametrów JVM w środowisku Intellij 13

W kolejnym artykule, postaram się opisać, jak powinno wyglądać prawidłowe odśmiecanie kodu :)

Źródła

  • Java Performance, Binu John, Charlie Hun 
  • http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html
  • http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html?cid=6628&ssid=0
  • https://www.youtube.com/watch?v=DoJr5QQYsl8
  • Internet :)

 

niedziela, 6 kwietnia 2014

Konfiguracja sieci Eduroam PK na Windows 8

Wstęp

Konfiguracja sieci Eduroam (USK PK Czyżyny) na systemie Windows 8 niestety nie należy do łatwych i  intuicyjnych czynności instalacyjnych. O ile konfiguracja na starszych systemach oraz na urządzeniach mobilnych jest dość dobrze opisana w sieci, o tyle w Windowsie 8 nastarcza wiele trudności z powodu usunięcia przez Microsoft pola wyboru szyfrowania WPA z graficznego kreatora sieci. Jest to bardzo dziwne zachowanie, gdyż WPA jest następcą mniej bezpiecznego standardu WEP, który mimo wszystko w kreatorze występuje. Niemniej jednak WPA-Personal oraz  WPA-Enterprise jest wspierany przez system operacyjny - należy tylko utworzyć profil sieci na ustawieniach WPA2 i ręcznie wymusić zmianę szyfrowania poziomu linii komend.

Poradnik przedstawia pełną konfigurację profilu sieci Eduroam dla certyfikatu osobistego wystawionego przez Politechnikę Krakowską na systemie Windows 8 (oczywiście Windows 8.1 również, gdyż jest to zaktualizowany system Windows 8) i z racji istnienia wielu poradników dla instalacji certyfikatu - ta część instalacyjna zostanie pominięta.

Konfiguracja

Pierwszym ważnym krokiem jest upewnienie się, że w systemie nie ma utworzonego profilu sieci o nazwie "eduroam" (np. po nieudanych próbach samodzielnej konfiguracji sieci). W tym celu należy przejść od wiersza poleceń, w Windowsie 8 najprostszą metodą jest wejście kafelkowe menu i bezpośrednie wpisanie tam "cmd" i wciśnięcie enter. Aby sprawdzić listę dostępnych profili sieciowych należy wpisać polecenie:
netsh wlan show profiles
Jeżeli na liście profili znajduje się eduroam (Rys. 1), to należy go usunąć komendą:
netsh wlan delete profile name="eduroam"

Rys. 1 Lista dostępnych profili sieciowych w systemie.

Następnym krokiem jest przejście do Centrum sieci i udostępniania.  W tym celu należy rozwinąć menu kontekstowe na ikonce sieci w zasobniku systemowym i wybrać Otwórz Centrum sieci i udostępniania (Rys. 2).

Rys. 2 Zasobnik systemowy z rozwiniętym menu na ikonie sieci.

Następnie w celu utworzenia nowego profilu sieci bezprzewodowej należy wybrać kolejno Skonfiguruj nowe połączenie lub nową sieć (Rys. 3) oraz Ręczne nawiązanie połączenia z siecią bezprzewodową (Rys. 4).

Rys. 3 Okno Centrum sieci i udostępniania.

Rys. 4 Okno konfiguracji nowego połączenia lub sieci.

W kolejnym oknie, należy uzupełnić wstępne dane na temat nazwy sieci - eduroam oraz typ zabezpieczeń - WPA2-Enterprise (Rys. 5). Na całe szczęście, graficzne interfejsy zabezpieczeń WPA2-Enterprise oraz WPA-Enterpise w konfiguracji są takie same, więc cała konfiguracja może zostać przeprowadzona raz, bez konieczności rekonfiguracji po zmianie typów szyfrowania. Po ustawieniu tych danych można przejść dalej i w kolejnym oknie należy wybrać Zmień ustawienia połączenia (Rys. 6).

Rys. 5 Okno ręcznego nawiązywania połączenia z wypełnionymi danymi.

Rys. 6 Okno umożliwiające przejście do zaawansowanych ustawień sieci po dodaniu profilu.

Po przejściu do zakładki Zabezpieczenia, należy wybrać z rozwijalnej listy wyboru uwierzytelniania sieci opcję: Microsoft: Karta inteligentna lub inny certyfikat (Rys. 7).

Rys. 7 Okno Właściwości sieci bezprzewodowej.

Z poziomu okna dialogowego Właściwości sieci bezprzewodowej, należy teraz wykonać dwie równie ważne operacje. Pierwszą z nich jest kliknięcie przycisku Ustawienia (Rys. 7a) i odznaczenie w nowym oknie pola wyboru: Sprawdź tożsamość serwera, weryfikując certyfikat (Rys. 8).

Rys. 7a Przejście do ustawień certyfikatu. Rys. 8 Wyłączenie sprawdzenia tożsamości serwera.

Drugim ważnym krokiem jest kliknięcie przycisku Ustawienia zaawansowane (Rys. 7b). W nowo otwartym oknie, tym razem należy zaznaczyć pole wyboru Określ tryb uwierzytelniania, a następnie należy wybrać z listy rozwijalnej opcję Uwierzytelnianie użytkownika (Rys. 9). Po potwierdzeniu wyboru przyciskiem OK, należy zamknąć okno Właściwości sieci bezprzewodowej klikając również na przycisk OK.

Rys. 7b Przejście do zaawansowanych ustawień sieci. Rys. 9 Określenie trybu uwierzytelniania użytkownika.

Na tym etapie konfiguracja profilu sieci dla typu zabezpieczenia WPA2-Enterprise jest zakończona. Próba połączenia się z siecią Eduroam jest teraz kompletnie niemożliwa co z resztą sugestywnie przedstawia ikonka przy wyborze dostępnych sieci WiFi. Nadszedł więc czas na zmianę w utworzonym profilu sieci typu zabezpieczenia na WPA. W tym celu należy ponownie przejść do menu kafelkowego, wpisać "cmd", potwierdzić enterem i wprowadzić następującą komendę:
netsh wlan set profileparameter name="eduroam" authentication=wpa encryption=tkip
Uwaga: linia poleceń nie obsługuje skrótu klawiszowego ctrl+v, więc aby ułatwić sobie życie, wystarczy klikając prawym przyciskiem myszy rozwinąć menu kontekstowe i wybrać opcję Wklej (Rys. 10).

Rys. 10 Linia komend z prowadzonym poleceniem do modyfikacji typu szyfrowania.

Jeśli wszystkie operacje przebiegły pomyślnie to typ zabezpieczeń w profilu sieci eduroam powinien zostać poprawnie zmieniony (Rys. 11).

Rys. 11 Potwierdzenie pomyślnego wprowadzenia zmian w typie szyfrowania sieci na WPA.

Teraz już można przejść do listy wyboru aktywnych sieci WiFi, wskazać eduroam i po wybraniu odpowiedniego certyfikatu można cieszyć się pełnym dostępem do sieci :-).

Dodatkowe utrudnienia

Jak się okazuje, niestety sama poprawna konfiguracja profilu sieci eduroam niekoniecznie nie przysparza dodatkowych problemów i czasem mimo wszystko dostęp do sieci jest niemożliwy. W takich przypadkach ponowna instalacja certyfikatu pozwala rozwiązać problem.

Na koniec...

Chciałbym zaznaczyć, że wszystkie przedstawione w poradniku zrzuty ekranu są mojego autorstwa i mogą zostać rozpowszechniane pod warunkiem zawarcia informacji o ich pochodzeniu.

Dzięki za dotrwanie do końca! Mam szczerą nadzieję, że niniejszy poradnik przysłuży się ludzkości walczącej z niezrozumiałymi elementami systemu Windows i przestarzałymi zabezpieczeniami :-)