Angular End-To-End testing ja Protractor, kuvaruutukaappaukset

Olen testaillut Angular-koodia reippaasti Protractorilla, ja taannoin tuli ajankohtaiseksi pohtia miten voi tarkemmin tutkia miksi joku protractor test case epäonnistuu. Tässä muutama vinkki siihen:

Protractoriin voi asentaa kuvaruutukaappaus-ohjelman, näin:

npm install protractor-screenshot-reporter

Sen voi säätää makunsa mukaan ottamaan kuvia aina, tekemään niistä raportin, tai ottamaan vain epäonnistuneista testeistä otoksia, näin:

 

var ScreenShotReporter = require('protractor-screenshot-reporter');

exports.config = {
  // your config here ...

  onPrepare: function() {
    // Add a screenshot reporter and store screenshots to `/tmp/screenshots`:
    jasmine.getEnv().addReporter(new ScreenShotReporter({
       baseDirectory: '/tmp/screenshots',
      takeScreenShotsForSkippedSpecs: true,
      takeScreenShotsOnlyForFailedSpecs: true
   }));
  }
}

Tuo plug-in ottaa kuvia vain testin päätteeksi. Voit myös ottaa omia kaappauksia mistä vaiheista vain, tähän tapaan:

var fs = require('fs');

function writeScreenShot(data, filename) {
 var stream = fs.createWriteStream(filename);
 stream.write(new Buffer(data, 'base64'));
 stream.end();
}

browser.takeScreenshot().then(function(png) {
 writeScreenShot(png, 'exception.png');
});

Jos haluat päästä käsiksi selaimen logeihin, tässä koodia siihen:

browser.manage().logs().get('browser').then(function(browserLogs) {
  // browserLogs is an array of objects with level and message fields
  browserLogs.forEach(function(log) {
    if (log.level.value > 900) { // it's an error log
      console.log('Browser console error!');
      console.log(log.message);
    }
  });
});

Pitäisiko testissä odotella hetki? Onnistuu ProTractorissa, näin:

browser.sleep(5000);

Pitäisikö selain läväyttää koko ruudun kokoiseksi? Onnistuu, näin:

browser.driver.manage().window().maximize();

Näin voit poistaa evästeet – esim. ennen kirjautumista:

 // delete all cookies
 browser.manage().deleteAllCookies();

Kenties hyvä idea kääntää jquery animaatiot pois päältä testauksen ajaksi – välttääksesi viiveitä esim. navigaatiopalkkien esiintulossa tms:

 // disable jQuery animation effects
 browser.driver.executeScript("$.fx.off = true;");

Onko muita hyviä Protractor tai JavaScript e2e-testausvinkkejä?

High Availability Mysql: Galera Cluster ja haproxy

Kun sovelluspalvelin on vikasietoinen ja vakaa, on aika tuunailla tietokantakerrosta. Vikasietoisessa järjestelmässä olisi suotavaa että myös tietokannasta on useampi kopio, jotta tietoa ja tapahtumia ei katoa vaikka tapahtuisi normimaanantai.

Sain vinkin Galera klusterituotteesta jolla Mysql kannat saa replikoimaan nätisti. Sen eteen tarvitaan joku kuormantasaus, ja testailemani haproxy vaikutti enemmän kuin riittävältä siihen. Lähtökohtana tulisi olla vähintään kolmen noden rinki, jotta enemmistö voi ristiriitatilanteissa äänestää nurin vähemmistön (2 vs 1 ei ole ehkä reilua, mutta se antaa vähän enemmän takeita siitä mikä on validein tieto – jos kaikki ovat eri mieltä ollaankin pulassa). Rakentelin kuitenkin enemmän proof-of-concept ideana parista nodesta klusteroidun, vikasietoisen mysql härvelin johon kytkeydytään Glassfish connection poolin kautta. Ja hyvältä vaikuttaa!

Huom! Kahden noden mallissa voi odotaa tulevan enemmän virhetilanteita, jotka voivat vaatia mysql boottausta ja replikoinnin resetointia. Hyödylliseksi on osoittautunut komento: sudo rm -r -f /var/lib/mysql/grastate.dat

Tässä siis muistiinpanoja ja rakennusohjeita. Huom! Joku muu voi tuunatata tämän eri tavalla ja ilmiselvästi tuotantokäyttöön tarvitaan toinen kierros koventamista, mutta näillä ohjeilla pitäisi päästä perille jos haluat maistella vikasietoisuutta itsekin. MariaDB on ehkä jopa paremmin tuettu nykyisellään jos haluat hakea MySQL:lle vaihtoehtoa.

Mysql + Galera replikoiva klusteri

Asennukset ensin. Tarkista, että olet ajan tasalla, ja asenna sitten MySQL + wsrep patchi ja Galera:

sudo apt-get update

sudo apt-get dist-upgrade

sudo apt-get install libaio1 libdbi-perl libdbd-mysql-perl mysql-client rsync

sudo wget http://ftp.de.debian.org/debian/pool/main/o/openssl/libssl0.9.8_0.9.8o-4squeeze14_amd64.deb && sudo dpkg -i libssl0.9.8_0.9.8o-4squeeze14_amd64.deb

sudo wget https://launchpad.net/codership-mysql/5.5/5.5.34-25.9/+download/mysql-server-wsrep-5.5.34-25.9-amd64.deb && sudo dpkg -i mysql-server-wsrep-5.5.34-25.9-amd64.deb

sudo wget https://launchpad.net/galera/3.x/25.3.5/+download/galera-25.3.5-amd64.deb && sudo dpkg -i galera-25.3.5-amd64.deb

Seuraavaksi tehdään mysql:ään vähän tunnuksia:

sudo /etc/init.d/mysql start

mysql -u root -p

#root on ylijumala ja sillä on salasana
GRANT ALL ON *.* TO root@'%' IDENTIFIED BY 'munsalainensana';

#galera haluaa myös päästä kiinni kantoihin
GRANT ALL ON *.* to sst@'%' IDENTIFIED BY 'sstpasswd';

# ja aikanaan myös haproxy haluaa tietää ovatko kannat pystyssä
INSERT INTO mysql.user (Host,User) VALUES ('%','haproxy');

flush privileges;

Hyvä, pistetään mysql automaattikäynnistymään:

sudo  update-rc.d mysql defaults

Editoidaan mysql wsrep.cnf tiedostoa tähän tapaan:

sudo nano /etc/mysql/conf.d/wsrep.cnf

Make these changes:

# Full path to wsrep provider library or 'none'
wsrep_provider=/usr/lib/galera/libgalera_smm.so

# Group communication system handle
wsrep_cluster_address="gcomm://"

# State Snapshot Transfer method
wsrep_sst_method=rsync

# SST authentication string. This will be used to send SST to joining nodes.
# Depends on SST method. For mysqldump method it is root:
wsrep_sst_auth=sst:sstpasswd

Sitten vain mysql käynnistäen uudelleen

sudo /etc/init.d/mysql restart

Hyvä, nyt olisi yksi node pystyssä. Kakkosnodelle tehdään samat operaatiot muuten, mutta editoitaessa tämä yksi rivi muuttuu vähän: siihen tulee ykkösnoden nimi tai ip-osoite:

# Group communication system handle
wsrep_cluster_address="gcomm://debian1,debian2"

Mutta muuten käy läpi samat temput. Kun olet valmis, jos ei mysql käynnistyksessä ole ollut ongelmia, buuttaa ensin node1, sitten node2 pienellä viiveellä.

Ei ongelmia? Hyvä, kirjaudu mysql:ään haluamallasi tunnuksella ja salasanalla, ja aja seuraava komento:

show status like '%wsrep%';

Kiinnitä huomioita erityisesti kohtiin wsrep_ready (pitäisi olla ON), ja wsrep_cluster_size (pitäisi olla 2).

Jos pääsit tähän asti, onnittelut. Jos et, vedä syvään henkeä, ja aloita uudet toistot.

Voit todeta klusterin toimivuuden esim. kirjautumalla toiseen nodeista ja lisäämällä johonkin tauluun rivejä. Niiden pitäisi ilmestyä pikimmiten myös toiseen kantaan.

Haproxy asentaminen Galeran päälle

Hauskasti haproxy ei löydykään oletuksena debianin wheezystä, joten lisätään listalle uusi site. Editoi /etc/apt/sources.list tiedostoa, lisää sinne tämä:

deb http://ftp.debian.org/debian/ wheezy-backports main

Aja seuraavat komennot asentaaksesi haproxyn:

sudo apt-get update

sudo apt-get install haproxy -y

sudo service haproxy start

Pistetään se myös automaattikäynnistykseen:

sudo sed -i s/0/1/ /etc/default/haproxy

Editoi myös /etc/init.d/haproxy tiedostoa, aseta sinne ENABLED arvoon 1 (oletuksena 0).

Seuraavaksi varmuuskopioidaan haproxy.config, ja editoidaan sitä vähän:

mv /etc/haproxy/haproxy.cfg{,.original}
sudo nano /etc/haproxy/haproxy.cfg

Kopioi/editoi sinne jotain tämäntapaista:

global
  log 127.0.0.1   local0
  log 127.0.0.1   local1 notice
  #log loghost    local0 info
  maxconn 1024
  #chroot /usr/share/haproxy
  user haproxy
  group haproxy
  daemon
  #debug
  #quiet

defaults
  log     global
  mode    http
  option  tcplog
  option  dontlognull
  retries 3
  option redispatch
  maxconn 1024
  timeout connect 5000ms
  timeout client 750000ms
  timeout server 750000ms

listen galera_cluster 0.0.0.0:3307
  mode tcp
  balance roundrobin
  option tcpka
  option mysql-check user haproxy
  server debian1 192.168.0.100:3306 check weight 1 maxconn 20
  server debian2 192.168.0.101:3306 check weight 1 maxconn 20
 
listen stats 0.0.0.0:9090
  mode http
  stats enable
  stats uri /
  stats realm Strictly\ Private
  stats auth myusername:mypassword

 

Aikalailla oletusasetuksilla mennään tässä. Mutta muutama mielenkiintoinen säätö tässä tapahtui:

– timeout client ja timeout server on nostettu 5 sekunnista 75 sekuntiin – koska sovelluspalvelinten connection poolit roikuttavat yhteyksiä hyvinkin pitkään auki, 60 sekuntia on tyypillinen aika – näin yhteydet pysyvät valideina

– galera cluster pyörii tässä samassa koneessa, portissa 3307. Mysql oletusportti on 3306. Tähän voisi varata eri koneen jossa olisi haproxy, mutta ajattelin itse replikoida senkin joka nodeen, eli haproxy pyörii joka koneessa portissa 3307, sieltä saa vikasietoista ja tasattua palvelua.

– Tuossa ip osoitteet 192.168.0.100 ja 101 edustavat mysql servereitä joille kuormaa tasataan, listaan tosiaan lisää mieluusti ainakin yksi node lisää. Olen asettanut maksimiyhteysmäärän 20 kappaleeseen – tämäkin voisi olla hyvä synkata connection poolin kanssa. weight eli painotus on joka nodella tässä sama  – eli kuorma jaetaan tasaisesti.

– lopuksi on stats serveri, portissa 9090 (jonka tulisi olla vapaa) – se kertoo mukavasti selaimella tietoa haproxy toiminnasta ja nodejen tilasta. Keksi sille haluamasi osoite, portti, tunnus ja salasana, ja sitten vain testaamaan.

No niin, nyt sitten proxy käyntiin:

sudo service haproxy restart

Ja tämä tietysti joka nodessa, asennukset, säädöt ja käynnistykset.

Voit testata toimintaa esim:

telnet localhost 3307

Tai mysql clientille:

mysql -h 127.0.0.1 --port 3307 -u haproxy_root -p -e "SHOW DATABASES"

Ja voit myös ruuvata selaimesi osoitteeseen:

http://127.0.0.1:9090/stats

No niin, jos kaikki pelaa taas, voit seuraavaksi muuttaa glassfish serverisi connection poolin osoittamaan joko virtuaali-ip:hen, tai yksittäiseen haproxy nodeen, porttiin 3307 portin 3306 sijasta.

Glassfish vikasietoinen connection pool

On hyvä samalla tehdä vähän säätöjä; jos haluat connection poolin aidosti toipuvan proxyjen ja kantojen kaatumisista, hyvä tehdä seuraavaa:

Avaa mysql admin console, mene kohtaan resources-jdbc-connection pools – ja avaa connection pool jolla haluat klusteria käytellä.

Klikkaa ensin Ping ruutuun rasti, ja valitse Save.

Mene seuraavaksi Advanced välilehdelle ja tee tällaisia säätöjä:

  1. Validate At Most Once: 60 seconds
  2. Creation Retry Attempts: 3
  3. Retry Interval: 10 (taitaa oletuksena jo ollakin)
  4. Connection Validation: (Tick) Required
  5. Validation Method: custom-validation
    1. validation class name: org.glassfish.api.jdbc.validation.MySQLConnectionValidation (select from list)

Ja mitä muita säätöjä vain haluatkaan. Sitten vain Save ja mahdollisesti restart. Ja kokeilemaan.

Ja mikä hienointa – itse softan ei tarvitse mitenkään olla tietoinen vikasietoisuudesta tai kuormantasauksesta 😉

 

[edit]: Kahdella nodella tulee sitten tosiaan replikointipulmia aika ajoin, joissa korjaus on:

sudo rm /var/lib/mysql/grastate.dat
sudo service mysql restart

Joten vaivan välttämiseksi kannattaa pistää suosista kolme nodea pystyyn. Voisi olla metkaa tehdä kolmen noden Raspberry Pi-klusteri 😉

 

 

Tuossa muuten aika hyvä artikkeli hienommista tuunauksista:

https://www.digitalocean.com/community/tutorials/how-to-use-haproxy-to-set-up-mysql-load-balancing–3

 

 

Linux + Glassfish 4.0 High availability Load Balancing Cluster – osa 3

Viime kerroille rakensimme Glassfish servereistä klusterin, joka voisi elää vaikka virtuaalikoneissa tai Amazonin palveluissa. Pistimme sen eteen Apache Http-palvelimesta rakennetun Load Balancer ratkaisun – josta kannattaa myös tehdä High Availability ratkaisu, eli pistää niitäkin useampi kopio käyttöön. Vielä pitäisi saada aikaan se, että jos yksi Load Balancer kaatuu, muut ottavat sen paikan. Sitä pohdimme tällä kertaa.

Ideana on viritellä keepalived-niminen daemon ohjelma siten, että sille annetaan yksi yhteinen jaettu virtuaalinen ip-osoite. Keepalived reitittää sen ensisijaisesti ykköskoneelle, mutta jos se kaatuu, kakkoskone ottaa virtuaalisen ip:n haltuunsa. Näin ollen elleivät kaikki load balancerit kaadu yhtäaikaa, palvelun pitäisi pyöriä lähes katkotta.

Tässä esimerkissä virtuaalinen ip-osoite on 192.168.1.100, ja sen takana olevien koneiden todelliset ip-osoitteet voivat olla vaikkapa 192.168.1.101, 102, 103, jne – niitä ei tässä esimerkissä käytetä, vaan koneiden domain nimiä, jotka ovat edelleen debian1, debian2, jne.

Ensin asenna keepalived joka nodelle:

sudo apt-get install keepalived

Seuraavaksi editoi keepalived konfiguraatiota – sitä ei alussa ole ollenkaan, joten aloitetaan tyhjästä:

sudo nano /etc/keepalived/keepalived.conf

Ensimmäiselle koneelle, joka on oletuksena master, kopioi tiedostoon jotain tämäntapaista:

vrrp_script chk_http_port {   # Requires keepalived-1.1.13

script "wget -q -T 1.0 -t 2 --delete-after -O /tmp/test.wget http://localhost:80/index.html"

interval 5            # check every 5 seconds

weight 2              # add 2 points of prio if OK

}

vrrp_instance VI_1 {

interface eth0

state MASTER          # MASTER debian1, BACKUP debian2

virtual_router_id 51  # same id in both hosts

priority 101          # 101 on master, 100 on backup

virtual_ipaddress {

192.168.1.100         # virtual IP

}

track_script {

chk_http_port

}

}

 

Ja kakkoskoneelle modifioidaan tuota vähän, tähän tapaan:

 

vrrp_script chk_http_port {   # Requires keepalived-1.1.13

script "wget -q -T 1.0 -t 2 --delete-after -O /tmp/test.wget http://localhost:80/index.html"

interval 5            # check every 5 seconds

weight 2              # add 2 points of prio if OK

}

vrrp_instance VI_1 {

interface eth0

state BACKUP          # MASTER debian1, BACKUP debian2

virtual_router_id 51  # same id in both hosts

priority 100          # 101 on master, 100 on backup

virtual_ipaddress {

192.168.1.100         # virtual IP

}

track_script {

chk_http_port

}

}

 

Eli muuten sama, mutta prioriteetti vähän pienempi, ja tilana tosiaan BACKUP. Toki sovelletaan sen mukaan onko verkkokortti eth0, ja löytyykö serverin juuresta index.html tiedosto jolla voi testata vastaako serveri, miten tiheään haluat pollailla, jne.

Mutta viiden sekunnin välein siis testataan löytyykö index.html tiedostoa – jos ei, serverin prioriteetti nousee kahdella. Eli jos molemmat serverit ovat pystyssä, debian1 prioriteetti on 101+2 eli 103, ja debian2 on 100+2 eli 102, eli debian1 saa virtuaalisen ip-osoitteen. Jos ykkösserveri kaatuu, sen prioriteetti laskee 101+0, eli 101, ja näin debian2 saa virtuaalisen ip-osoitteen.

Lopuksi potkaistaan keepalived käyntiin ja testataan:

sudo service keepalived start

Ota yhteyttä selaimella virtuaaliseen ip-osoitteeseen – voit testata suoraan aiemmin käytettyä clusterjsp-sovellusta:

http://192.168.1.100/clusterjsp

Toimiiko? Hyvä. Oletuksena kytkeydyit varmaankin debian1 koneeseen, sekä apache että glassfish instanssiin. Seuraavaksi voitaisiin nitistää debian1 koneen glassfish:

sudo service glassfish-inst stop

Toimiiko? Hyvä, en olisi uskonut. Debian1 koneen apache ohjaa kuorman debian2 koneen glassfish serverille. Nitistetään seuraavaksi debian1 koneen apache:

sudo service apache2 stop

Kokeile vielä kerran virtuaali-ip:tä. Nyt sen pitäisi ohjata debian2 koneen apachelle, joka ohjaa debian2-koneen glassfishille.

Jos ei toimi, mokasit. Savun hälvettyä tarkista kytkennät ja yritä.uudestaan. Paljon on säätöjä näissä. Mutta metkasti toimii 😉 Kannattaa vielä buutata palvelimet ja katsoa että kaikki pelaa edelleen.

 

No niin, ja tässä pari kuvaruutukaappausta high availabilitystä toiminnassa. Olen hieman retusoinut serverinimiä ja ip osoitteita suojellakseni alkuperäisten tietokonehenkien identiteettiä ja persoonaa julkisuudelta, mutta näistä käy idea selväksi:

HAClient_1

Eli sessioon on pumpattu vähän dataa, tässä välissä kävin Glassfish konsolissa nitistämässä debian1 instanssin.

HAClient_2

Ja heittämällä mentiin kakkosnodelle, sessio data replikoituneena verkon yli ja edelleen käytettävissä ilman käyttäjälle näkyvää katkosta. Samoin voisi nitistää kumman hyvänsä load balancerin, tai vaikka vetää töpselin seinästä koko koneesta.

 

Nyt kun saisi vielä tietokantakerroksen vikasietoiseksi ja kuormaa tasaavaksi…..

Nexus 5, Nexus L ja Chromecast

Nexus 5 takakansi

Vaihteeksi Android päivitystä. Omat Android-laitteeni jostain syystä joutuvat aina koville, varsinaiseen elämän kenttätestiin. Ne lentelevät käsistä, tipahtavat kylpyammeeseen, ryömivät kanssani mudassa tai pehmentävät osumaa kiviin. Tästä syystä useampi kuin yksi on kehittänyt vikoja joita olen saanut joskus jopa korjatuksi kiitos Amazonin parin taalan varaosien 😉

Joka tapauksessa, viikonloppuna onnistuin taas paiskomaan Nexus 5:ni pitkin lattioita, ja sen seurauksena yllättäen GPS sanoi sopimuksensa irti. Ilman navigointia olen taas kuin kuuro lepakko – joten aloin ihmettelemään mistä kiikastaa ja miten korjataan/mistä uusi. Ongelmana on että akkukestoa lukuunottamatta pidän kovasti nykyisestä kirkkaanpunaisesta Nexus 5 luuristani, eli mieli ei tehnyt vaihtaa.

No onneksi ongelman syy löytyi, ja sain sen korjattua: Nexus 5 takakansi ei ehkä virallisesti ole irroitettavissa mutta kyllä se irtoaa. Ja siinä kannessa on konktaktinastoja jotka liittyvät mm. gps:ään. Kansi oli vähän raollaan ja gps-nastat irti. Puristin sen kiinni ja johan alkoi gps toimimaan. Mutta siinä meni sitten qi-langaton lataus rikki. Joten kansi kokonaan irti, huolellisesti alhaalta puristaen paikalleen, kaikki nastat kohdalleen, ja nyt näyttäisi toimivan taas kaikki. Eli Nexus 6:sta odotellessa… 😉

Tämä siis vinkiksi, samoin kuin tämä: Jos luuri pääsee kastumaan, esim. tipahtaa kylpyammeeseen tai on taskussa festareilla, irrota takakansi, irrota akku pikimmiten, sitten pistä se yön ajaksi pussiin joka on täynnä riisiä. Ja hyvä tulee taas.

Nexus L

Nexus L on tosiaan tekeillä, ja näyttää aika mukavalta, etenkin se akkukesto-osa ja uusi käyttöliittymälook. Google on julkaissut early access romit jotka voi päivittää mm. Nexus 5 tai Nexus 7 kakkosversioon. Löytyy täältä:

http://developer.android.com/preview/setup-sdk.html

Hyvä toki huomata että nämä ovat early access preview tavaraa ja luultavasti monetkin appsit kieltäytyvät yhteistyöstä ja bugeja on pilvin pimein, samoin kuin vajavaisia ominaisuuksia.

Turvallisemmin voit leikkiä uusilla versioilla päivittämättä Android emulaattorin uuteen ja rakentamalla sinne Nexus5/7 pohjaisen Android L virtuaalikoneen.

Näistä on sittemmin tehty muillekin malleilla sopivia epävirallisia ROM:eja, esim. Nexus4 jne. xda-developers tarjoaa ohjeita:

http://forum.xda-developers.com/google-nexus-5/development/rom-n5-l-developer-preview-t2796003

http://forum.xda-developers.com/nexus-4/development/lpv-79-mako-port-beta-t2807446

Chromecast screen mirroring

Jep, Chromecast sai sitten luvatun screen mirroring-patchin Se tarkoittaa, että Nexus-laitteista voi heittää koko ruudun chromecastin kautta televisioon tai videoprojektoriin, ei pelkästään tuetuista sovelluksista kuten aiemmin. Nexus-laitteissa löytyy tämä optio suoraan asetuksista kunhan chromecast-ohjelma on asennettu ja yhteys tikkuun muodostettu.

Tätä piti kokeilla heti: itse olen ollut vähän skeptinen tämän sujuvuuteen ja viiveisiin nähden, mutta ilokseni voin todeta että sujui, ei viiveitä. Pistin kameraa päälle ja heitin sitä livenä televisioon langattomasti, ja hyvin sujui vailla nykimisiä.

2014-07-09 20.59.32

Sellaista tällä kertaa. Olisi hienoa kun aika sallisi taas vähän koodailla Androidia ja Glass-alustaa, mutta ei pysty koska kesä.

Linux + Glassfish 4.0 High availability Load Balancing Cluster – osa 2

Viime kerralla viritettiin kaksi Glassfish serveriä juttelemaan keskenään – ja tarvittaessa replikoimaan istunnotkin. Tällä kertaa laitetaan niiden eteen Apache Http serveri LoadBalanceriksi. LoadBalancerin tehtävänä on ohjata liikenne toimiville servereille ja ohittaa vikatilassa tai sammuneina olevat – sekä tasata kuormaa serverien välillä. Näitäkin kannattaa tehdä ainakin kaksi kappaletta – yksi joka instanssikoneeseen – koska muuten loadbalancer on uusi kriittinen pisteesi – heikoin lenkki.

Aloitin ensin MOD_JK:lla, koska se on load balancer vaihtoehdoista ’javamaisempi’, joka tarkoittaa että se osaa tehdä monenmoisia temppuja mitä muut eivät osaa, mm. ssl-salauksen, monitoroinnin ja dynaamisten säätöjen suhteen. Valitettavasti testatessa paljastui, että vaikka se toimi hienosti clusterjsp esimerkille, se antoi suurikokoisilla tiedostoilla mehukkaita Grizzly-poikkeuksia (mm. HeapBuffer has already been disposed). Tämä on ilmeisesti Glassfish 4.0 bugi – en ollut ainoa joka tästä kärsi. Kenties 4.1 korjaa tämän – 4.0:han on tarkoituskin olla high availability early access versio. Mutta kärsimätön mieli ei jaksa eikä pysty odottamaan. Joten tein ratkaisun mod_proxyllä. Listaan kuitenkin testatut mod_jk käyttöönotto-ohjeet tähän samaan artikkeliin – loppuun. Mutta ensin mod_proxy ja toimiva versio:

MOD_PROXY Load balancer asennusohjeet

Ohjeissa oletetaan että koneet joihin asennat nämä ovat nimeltään debian1 ja debian2, ja asennat kaiken joka koneelle.

Aloita asentamalla ja aktivoimalla tarvittavat moduulit:

sudo apt-get install apache2 libapache2-mod-proxy-html libxml2-dev

sudo a2enmod proxy proxy_http proxy_balancer rewrite

Testaa käynnistyykö apache2:

sudo service apache2 start

Jos kaikki hyvin, seuraavaksi editoi tiedostoa /etc/apache2/sites-available/default lempieditorillasi. Sen voisi muokata esim. tämän näköiseksi (muista muokata se klusterin kaikille koneille, ja vastaavasti muutaa host name osia, jotta load balanceristä on kopioita):

<VirtualHost *:80>
 ServerName debian1.mycompany.com
 ServerAdmin webmaster@localhost

 ErrorLog ${APACHE_LOG_DIR}/error.log

 # Possible values include: debug, info, notice, warn, error, crit,
 # alert, emerg.
 LogLevel warn

 CustomLog ${APACHE_LOG_DIR}/access.log combined

 RewriteEngine On
 ProxyRequests Off
 ProxyPreserveHost On

 <Proxy *>
 Order deny,allow
 Allow from all
 </Proxy>

 <Location /balancer-manager>
 SetHandler balancer-manager
 Order Allow,Deny
 Allow from all
 # Only allow from internal network
 #Allow from 10.0.0.0/8
 </Location>

 <Proxy balancer://mycluster>
 BalancerMember http://debian1:8080 route=debian1
 BalancerMember http://debian2:8080 route=debian2
 ProxySet lbmethod=byrequests
 </Proxy>

 ProxyPass /balancer-manager !
 ProxyPass / balancer://mycluster/ stickysession=JSESSIONID
 ProxyPassReverse / http://debian1:8080/
 ProxyPassReverse / http://debian2:8080/

</VirtualHost>

Käynnistä apache uudelleen, ja kokeile ohjata selaimesi load balancer-koneen osoitteeseen. Sen pitäisi ohjata vuoronperään eri myllyille – voit testata tätä vaikkapa avaamalla pari eri selainta, tai sammuttamalla ykkösmyllyn. Proxypasseja voi tietysti lisätä ja muokata sen mukaan mitä kaikkia kansioita haluat uudelleenohjata ja miten. Load balancer algoritmejakin löytyy useampia.

No niin, seuraavaksi vaihtoehtoiset ohjeet mod_jk versiolle. Sitä en itse päätynyt käyttämään, mutta se voi olla testaamisen arvoinen Glassfish 4.1 kanssa aikanaan.

MOD_JK load balancer asennusohjeet

Aloita asentamalla softat kaikille haluamillesi koneille:

sudo apt-get install apache2 libapache2-mod-jk

Voisit tässä kohtaa editoida tiedostoa /etc/apache2/mods-available/jk.conf  – mutta siellä ei ole mitään pakollista muutettavaa, joten mennään sensijaan suoraan editoimaan toista tiedostoa:

sudo nano /etc/libapache2-mod-jk/workers.properties

Editoi tätä tiedostoa, voit kommentoida pois esim. oletus-jk13 workerin säätöjä, mutta muuta yksi riveistä tällaiseksi:

worker.list=loadbalancer,jk-status

Ja lisää tämätapaista (jos laitteita on enemmän kuin kaksi, lisää rivejä vain – tietysti sovella verkkonimet jne):

worker.debian1.port=8009
worker.debian1.host=debian1.mycompany.com
worker.debian1.type=ajp13
worker.debian1.lbfactor=1
worker.debian2.port=8009
worker.debian2.host= debian2.mycompany.com
worker.debian2.type=ajp13
worker.debian2.lbfactor=1
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=debian1,debian2
worker.loadbalancer.sticky_session=1
worker.jk-status.type=status

Huomaa miten voit load balance factoreilla esim. painottaa miten kutsuja jaetaan. Tässä on käytössä sticky_session joka ei ole välttämätöntä. Olemme jättäneet myös status-tiedot päälle. Huomaa että jk moduuli myös kirjoittelee logia oletuksena paikkaan /var/log/apache2/mod_jk.log – logit on hyvä tarkastaa aika ajoin näitä testatessa.

Hommaa alkaa olla melkein valmis. Seuraavaksi editoidaan apache serverin omaa oletuskonfiguraatiota, ja lisätään kaikki halutut hakemistot joita halutaan uudelleenohjata:

sudo nano /etc/apache2/sites-available/default

Ja konfiguraatio voi mennä esim. näin:

<Location /jk-status>
 # Inside Location we can omit the URL in JkMount
 JkMount jk-status
 #Order deny,allow
 #Deny from all
 #Allow from 127.0.0.1
 </Location>

# mount clusterjsp
 JkMount /clusterjsp loadbalancer
 JkMount /clusterjsp/* loadbalancer

Nämä tulevat tietysti kaikki juurielementin VirtualHost sisään, loppuun, ja jos haluat lisää hakemistoja loadbalanceriin clusterjsp:n lisäksi, määrittele ne kaikki tähän.

Seuraavaksi enabloidaan mod_jk (luultavasti jo päällä), buutataan apache, ja aletaan kokeilemaan:

sudo a2enmod jk
sudo /etc/init.d/apache2 restart

Näppärä testi on ensin avata selain osoitteeseen http://debian1/clusterjsp – ja katsoa aukeaako sovellus. Apache pyörii portissa 80 – glassfishit porteissa 8080 omissa koneissaan. Jos sovellus toimii, näet miltä serveriltä se on noudettu. Nyt voit mennä glassfish hallintaan (DAS) ja sammuttaa instanssin joka on käytössä. Jos load balancer toimii oikein, sen pitäisi seuraavan kerran sivua päivitettäessä saumattomasti pompauttaa sinut toiselle instanssille.

Muista tehdä tämä load balancer molempiin/kaikkiin instansseihin niin voimme seuraavalla kertaa rakentaa siitäkin high availability version. Koska mitä jos Load Balancer kaatuu?

 

 

Maven, Glassfish 4 ja Cargo plugin

Kun hioo jatkuvaa integraatiota kuntoon tulee ennen pitkää ajankohtaiseksi pohdiskella miten automatisoidaan Maven buildien asennus etäservereille – kehittäjätestiservereille, hyväksyntätestiservereille, ja tuotantoonkin. Tapojahan tähän on monia – serverien omat työkalut, ihan tiedostotasolla toiminta ja hot deploy. Itse kuitenkin halusin kytkeä tämänkin Maveniin, se helpottaa kovasti mm. Jenkinsin kanssa toimintaa ja pitää munat samassa korissa.

Kokeilin muutamaa plug-inia, ja suosikiksi niistä erääntyi Cargo plug-in. Muissa tuli vastaan bugeja, ja Cargon konfiguraatio oli simppeleimmästä päästä joten se päätyi mukaan. Mukavaa on myös se, että Cargo ei ole yhden serverin ihme vaan tukee valtaisaa määrää Java Appservereitä.

Eli lisätään pom.xml tiedostoon tällainen plug-in:

 <!-- Maven Cargo plug-in to deploy .war to test servers -->
  <plugin>
    <groupId>org.codehaus.cargo</groupId>
    <artifactId>cargo-maven2-plugin</artifactId>
    <version>1.4.8</version>
    <configuration>
      <container>
        <containerId>glassfish4x</containerId>
        <type>remote</type>
      </container>
    <configuration>
      <type>runtime</type>
      <properties>
        <cargo.hostname>munserveri</cargo.hostname>
        <cargo.remote.username>muntunnus</cargo.remote.username>
        <cargo.remote.password>munsalasana</cargo.remote.password>
      </properties>
   </configuration> 
   </configuration>
    <dependencies>
      <dependency>
        <groupId>org.glassfish.deployment</groupId>
        <artifactId>deployment-client</artifactId>
        <version>3.2-b06</version>
      </dependency>
    </dependencies>
  </plugin>

Ja siinä se. Tuossa yllä munserveri on tietysti oman Glassfish 4 serverin osoite, muntunnus ja munsalasana sen admin-oikeudet omaavat tunnukset.

Nyt voit ajaa seuraavia komentoja:

mvn clean package cargo:deploy
mvn clean package cargo:redeploy
mvn cargo:undeploy

Yritin viritellä tätä toimimaan force-parametrilla siten että deploy hoitaisi myös redeploy-toiminnon – mutta jostain syystä ei pelittänyt ainakaan tässä ympäristössä. Ratkaisuna on ajaa aina cargo:redeploy, se ei näytä pahastuvan ellei serveriltä softaa ennestään löydykään, mutta deploy pahastuu jos softa on jo serverillä samalla nimellä, ja undeploy pahastuu jos softaa ei ole.

Seuraava askel on sitten tuunata profiileja käyttöön. Niillä voit säätää helposti serveriosoitteet, salasanat ja tunnukset vaikka miten monelle eri serverille ja käytellä niitä esim. näin:

mvn -Pintegration-test package cargo:undeploy cargo:deploy

Varmaan on fiksumpiakin tapoja tehdä näitä, esim. kenties force parametrin saa toimimaan, kenties redeploy hoitaa saman kuin undeploy+deploy. Tällä pääsee kuitenkin alkuun, ja kommentoida sopii jos keksii liukkaampia tapoja.

Plug-in on CodeHousin käsialaa ja löytyy täältä: http://cargo.codehaus.org/

 

 

Ja näin opimme taas jotain kivaa ja hyödyllistä 😉