tetoshop.com tetocserepshop.com mestercentrum.com

Archívum

A(z) ‘Tech’ kategória archívuma

Samsung Galaxy Spica frssítése Android 2.1-re

június 23rd, 2010 4 hozzászólás

Már régóta fontolgattam, hogy be kéne szereznem egy Android-os telefont. Kicsit körbenéztem az elérhető eszközök között, és a választásom a Samsung Galaxy Spica-jára esett. Ez a telefon ugyanis rendelkezik minden tudással, amivel a nagyok (WiFi, GPS, elviselhető teljesítményű processzor), az ára viszont kb. fele annyi (Extreme Digitálnál röpke 60 000 Ft). Mikor hozzájutottam, bekapcsolás után az első gondolatom az volt, hogy a telefonnal szállított 1.5-ös oprendszert 2.1-esre kellene cserélni. Kicsit utánaolvasgattam, és március környéki híreket találtam arról, hogy a Samsung hamarosan hivatalosan is elérhetővé teszi a 2.1-es firmware-t telefonjaira. Gyorsan fel is pakoltam a telefonhoz adott CD-ről a Samsung Kies nevű kezelőprogramját, és megpróbálkoztam a frissítéssel. Első körben a cucc fel sem ismerte a telefont, aztán valami modell adatbázist nem talált. Próbálkoztam a PC suite különböző változataival, a Kies-ből is töltöttem frisset, végül kb. fél napi tömény szenvedés után feladtam. Ezzel a telefon upgrade dologgal valahogy nincsenek a helyzet magaslatán. Végül úgy döntöttem, lesz ami lesz, felülvágom a firmware-t, mert nekem 2.1-es Android kell, ha a fene fenét eszik is.

A frissítést a http://forum.androidhungary.com/topic/samsung-galaxy-spica-android-21-flashing-utmutato alapján végeztem. Az Odin-t és a drivereket könnyen be tudtam szerezni, a firmware-hez kicsit szenvedni kellett, mert ilyen hülye fájlmegosztó oldalakról kellett lebányászni, amik mindenféle várakoztatásokkal próbálják rávenni az embert, hogy dobjon be némi pénzt. Mennyivel jobban örültem volna egy szimpla torrent linknek, de mindegy, leszenvedtem a firmware-t. Megnyomkodtam a gombokat, beállítottam a letöltést, betallóztam a fájlokat, aztán vártam, de nem történt semmi. Rájöttem, hogy a Kies még fut a háttérben. Lelőttem, újraindítottam az Odin-t, de a letöltő csík meg sem mozdult. Na, gondoltam, most vágtam tönkre a telefont, ugyanis kikapcsolni nem lehetett, a leírásban meg az ember lelkére kötik, hogy ne szakítsa meg a folyamatot. Végül aksi ki-be, bekapcsoltam a telefont, és hamar meg is könnyebbültem, mert simán bebootolt az eredeti 1.5-ös Android. Ezen kicsit fel is bátorodtam, hisz ebből látszott, hogy azért nem olyan könnyű tönkre vágni a telefont. Újra elindítottam a feltöltést az Odin-ből, de most valami cache fájl miatt nyavajgott. Végül rájöttem, hogy az Odin mellé csomagolt ops fájlban van a hiba, és a helyről, ahol a firmware-t is letöltöttem, letöltöttem az új ops-t. Felülvágtam a régit, elindítottam a frissítést, és minden smakkolt. Végigfutott a progress bar, telefon kikapcs-bekapcs, és az új 2.1-es Androidom fogadott. A beállításoknál visszaváltottam a nyelvet magyarra, és végre birtokba vehettem az újdonsült telefonomat.

Amúgy magával a telefonnal eddig nagyon meg vagyok elégedve, a Google szinkronizálás (címjegyzék, levelezés, gTalk, stb.) alap. A WiFi-t is rögtön belőttem, hogy ne is próbálkozzon 3G-n, mert nem szeretnék következő hónapban 10 000-es számlát kapni az adatforgalom miatt. Telepítettem még a market-ből egy eBuddy nevű üzenetküldő alkalmazást, ami kb. a Pidgin Androidos megfelelője (MSN, ICQ, stb. támogatás), és egy Skype Lite Beta-t. Talán még egy IGO hiányzik róla, hiszen a GMap-nak netkapcsolat kell, és utazás közben általában nem jut az ember WiFi-hez, a mobilnet pedig dárga.

UPDATE: A későbbiekben néhányszor próbáltam belőni a 3G-t, de nem jártam sikerrel. A megoldást végül egy kolléga segítségével sikerült megtalálni. Ahhoz, hogy a telefon csatlakozzon a 3G hálózatra, a Beállítások/Vezeték nélküli beállítások/Mobilhálózatok/Hozzáférési pontok neve menüpont alatt hozzá kell adnunk a szolgáltatóhoz tartozó APN-t, amiről itt találhattok egy listát. A beállítást követően remekül működik a 3G. A megoldás megtalálásáért külön köszönet Kercza Ádámnak.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)
Categories: Tech Tags:

Üzenet alapú programozás – Entourage és ErraiBus

június 8th, 2010 Nincsenek hozzászólások

Az utóbbi időben az ActiveMQ kapcsán kicsit mélyebben utánaolvastam az üzenet alapú rendszereknek. Nem annyira az ESB megoldások érdekeltek, hanem inkább az, hogy léteznek-e üzenet alapú web-es keretrendszerek. A közelmúltban 2 nagyon jó projektet is találtam. Ezek a címben is szereplő Entourage és ErraiBus.

Az Entourage az Appcelerator egyik alprojektje. Maga az Appcelerator egy olyan keretrendszer, melynek segítségével mobil és desktop alkalmazásokat készíthetünk HTML és JavaScript segítségével. Maga a futtató környezet egy beágyazott böngésző, valamint egy általános API gyűjtemény, amin keresztül JavaScript-ből hívhatóak az adott platform natív funkciói. Így ha egyszer összeraktuk a HTML/Javascript alkalmazást, azt minden változtatás nélkül futtathatjuk Android telefonokon, IPhone-on, és készülhet belőle desktop alkalmazás is. Igazából a rendszer önnmagában is megérdemelne egy saját post-ot, így többet nem is mondok róla, inkább az Entourage-re koncentrálok. Az Entourage egy JavaScript library, amelynek alapja egy üzenet sor (message queue). Az üzenet sorba üzeneteket rakhatunk be JavaScript-ből, illetve funkciókat ültethetünk rá egy-egy üzenetre. Ez így önmagában nem nagy dolog, az izgalmas igazából az, hogy a keretrendszer mi mindent ki tud hozni ebből az egyszerű architektúrából.

Az Entourage üzenetsorra épül az Entourage Expressions, ami tulajdonképpen egy HTML-be ágyazható DSL, aminek segítségével JavaScript nélkül valósíthatunk meg AJAX-os működést. Egyszerűen az adott HTML tag-et kell ellátnunk egy

 on="[condition] then [action]"

attribútummal. A condition rész tulajdonképpen egy esemény/üzenet az üzenet sorból, amit vagy mi tehetünk oda JavaScript segítségével, vagy a felhasználótól jöhet pl. click, hover, stb. Az action pedig ugyanúgy lehet egy újabb esemény küldése, vagy pedig valamilyen előre definiált működés pl. class attribútum cseréje, stb. Ezzel az egyszerű rendszerrel már eleve nagyon sok mindent meg lehet valósítani, mindezt JavaScript programozás nélkül egyszerű attribútumok használatával.

A következő szint az Entourage UI, ami tulajdonképpen egy az alsóbb szintekre épülő widget gyűjtemény. Itt egy control attribútum hozzáadásával definiálhatjuk a widget típusát és paramétereit, és annak szerkezetét általában a tag-ben szereplő HTML kód határozza meg (pl. ul/li tagok egy lista esetén). Ezzel az eszközzel már tulajdonképpen teljes AJAX-os felhasználói felületek építhetőek némi HTML tudással JavaScript ismerete nélkül.

Az utolsó komponens a Service Brokers, ami nekem a leginkább tetszett. A Service Broker-ek segítségével tulajdonképpen teljesen transzparens módon hozzákapcsolhatjuk a szerver oldali kódot az Ertourage alkalmazáshoz. A megoldás mindössze annyi, hogy a message queue-t úgy konfiguráljuk, hogy bizonyos üzeneteket a szerver felé továbbítson. JavaScript oldalról ez teljesen transzparens módon történik, hiszen ugyanúgy tudunk üzenetet küldeni a szerver felé, mint egy másik helyi komponens felé, ráadásul az egyszerű protokollnak köszönhetően szinte akármilyen programozási nyelven (Java,.NET, PHP, Python, stb.) és környezetben (Spring, Google App Engine, Pylons, stb.) készülhet a szerver oldal. Összességében tehát egy olyan rendszert kapunk, ahol – ha megelégszünk az alap készlettel -, JavaScript nélkül fejleszthetünk webalkalmazásokat úgy, hogy a szerver oldali keretrendszer teljesen szabadon választható.

A másik rendszer, ami az Entourage-hez hasonlóan üzenetkezelésen alapul, a JBoss egyik alprojektje, az ErraiBus. Az ErraiBus egy teljesen Java alapú rendszer. A rendszer kliens oldalát GWT-vel készíthetjük el, a szerver oldal futtatásához pedig valamilyen Java Servlet Container szükséges. A két oldal között egy üzenetsor segítségével kommunikálhatunk, tulajdonképpen ezt hívjuk ErraiBus-nak. Ha az előző megoldással hasonlítjuk össze, úgy hátrányának az mondható, hogy szorosan kötődik a Java nyelvhez (a GWT és a szerver oldal miatt is), ugyanakkor az előző light weight megoldáshoz képest ez igazi hard core megvalósítás, ugyanis az üzenetsor comet kapcsolaton keresztül működik, így tiszta kétirányú kommunikáció lehetséges. Nincs szükség külön poll-ozásra, és hasonló trükkökre, ugyanazzal az egyszerűséggel küldhetünk a szerverről a kliens oldalra, mint fordítva. Ez az architektúra tehát valóban real-time alkalmazásokat tesz lehetővé. Ha ehhez hozzágondolom, hogy GWT-ben már Quake-et is írtak, akkor látható, hogy egy ilyen rendszerrel a lehetőségek száma szinte végtelen. A transzparens működést pedig itt is az üzenet sor alkalmazása hozta.

A fentiek alapján úgy látom, hogy az üzenet alapú rendszerek előtt még nagy jövő áll, és sok esetben jelenthetnek nagyon kényelmes megoldást heterogén környezetben. Szerver oldalon az ESB és az ActiveMQ, kliens szerver kapcsolat esetén pedig az Entourage és ErraiBus jellegű alkalmazások. Én személy szerint szívesen látnék valamilyen egységes service bus megoldást, ami ezen rendszerek előnyeit egyesíti, tehát a buszra ugyanúgy “aggathatnánk” kliens oldali GWT alkalmazásokat, Appletteket, Flex, JavaScript, stb. alkalmazásokat, mint szerver oldali Java, PHP, .NET, stb. feldolgozókat, mindig az adott igényeknek megfelelően, sőt egy ilyen rendszerben sokkal szabadabban mozgathatnánk az egyes komponenseket, így ugyanazt a rendszert használhatnánk desktop környezetben (minden komponens a gépre kerül), webes, vagy mobil környezetben (bizonyos komponensek a szerveren maradnak).

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)
Categories: Tech Tags:

ActiveMQ, MorbidQ – üzenet alapú aszinkron kommunikáció heterogén rendszerekben

június 6th, 2010 Nincsenek hozzászólások

Nem olyan régen egy projekt kapcsán a következő problémába ütköztem: kényelmi szempontból egy heterogén rendszert készítettem, aminek voltak web-es PHP-s részei, néhány időzített offline PHP script, meg néhány Java-s komponens. Alapvetően egy weblapról van szó, ahol az ügyfél termékeket rendelhet meg (web-es PHP rész), majd a megrendelések alapján egy időzített Java process előállítja a felhasználó számár elkészült csomagot (Java komponens), végül egy offline időzített PHP script e-mailben elküldi a csomagot a felhasználónak (offline PHP rész).

Mivel a lehetőségek elég szűkösek voltak, valami nagyon egyszerű megoldást kellett találnom a kommunikáció megvalósítására. A megoldás szinte adta magát, a megrendeléseket tároló adatbázis tábla szolgált az adatok átadására. A webes alkalmazás felvette a megrendelést a táblába, aztán cron-al néhány percenként elindítottam a Java process-t, ami ellenőrizte, hogy van-e új megrendelés. Ha volt, legenerálta a csomagot és átbillentette a rendelés állapotát. Végül az ugyancsak cron-ból futtatott PHP process ellenőrizte, hogy van-e postázni való. Ha volt, elküldte e-mailben, és átbillentette az állapotot. A rendszer egész jól működik is, de azért nem hagyott nyugodni a gondolat, hogy hogyan lehetne ezt még hatékonyabban megcsinálni. Az egyik ötlet, hogy a PHP engine és a Java VM betöltődési overheadjét elkerülendő mindkét process-t démonként kellene futtatni cron nélkül. Így sok erőforrást lehetne megspórolni, hisz nem kell minden esetben újra elindítani a JVM-et/PHP script engine-t, és betöltögetni az osztályokat/scripteket. Ez viszonylag egyszerűen kivitelezhető. A másik dolog, ami már inkább gondolkodóba ejtett, hogy amit csináltam, az tulajdonképpen egy primitív message queue. A web alkalmazás bedobja a megrendelés üzenetet, amit a Java alkalmazás feldolgoz, majd bedob egy postázás üzenetet, ami pedig az időzített PHP process-nek szól. Ezt biztos lehetne valahogy általánosítani. Egy olyan queue megoldás körvonalazódott a fejemben, aminek célja több alkalmazás aszinkron kommunikációja, ahol az egyes komponensek bármilyen környezetben készülhetnek, így a megoldás teljesen platform független. Adatbázisban gondolkodtam, schedulerekben, és valami cross-platform (mondjuk JSON) kommunikációban. Végül ahogy szokott, kiderült, hogy nem én vagyok az első, akinek megfordult a fejében egy ilyen rendszer gondolata.

Olyannyira, hogy már nevet is adtak neki, Enterprise Service Bus-nak (ESB) hívják, és a célja pont az amit az előbbiekben felvázoltam. Egy közös üzenet soron alkalmazások lógnak, és minden típusú kommunikációhoz külön szál (topic) rendelhető. Ha az egyik komponens akar valamit a másiktól, egy üzenetet helyez az üzenetsorba, amit a másik feldolgoz, és persze a dolog működhet két irányban, tehát a feldolgozó komponens egy másik üzenet soron vissza üzenhet a feladónak. A megoldás nagy előnye, hogy ha az üzenetek valamilyen általános formában mozognak, a Service Bus-t kényelmesen használhatjuk valamilyen heterogén környezetben (mint pl. az általam vázolt rendelési rendszer). A másik nagy előny az aszinkron jelleg. Azt ugyanis nem említettem, hogy a megrendeléshez tartozó alkalmazás csomag generálása igen erőforrás igényes folyamat. Tehát nem csak azért kellett ezt a megoldást használnom, mert a PHP webalkalmazásból nehézkes Java-t hívni, hanem azért is, mert a generálás miatt könnyen timeout-olhatott volna a PHP script, vagy ha több megrendelés van egyszerre, azt nem biztos, hogy bírná a szerver. Így az üzenetsor nem csak a heterogén rendszerben történő kommunikációra, hanem az erőforrások elosztására is kiváló eszköz. A fentebb vázolt probléma általános megoldása tehát odáig egyszerűsödött,  hogy találjuk meg a megfelelő üzenetsor megoldást.

Olyan megoldás kell tehát, ami a legtöbb programozási nyelvben támogatott, nincs túl nagy erőforrás igénye, mégis megfelelően sokoldalú. Némi kutakodás után rátaláltam a STOMP protokollra. Ez a legtöbb programnyelvben támogatott üzenet protokoll, így ha heterogén rendszerekben (PHP, Java, Python, .NET, C++, stb.) működni képes megoldást keresünk, az nagyjából annyit tesz, hogy a megoldás legyen STOMP kompatibilis. Jelenleg két ilyen megoldást találtam, ezek között hezitálok.

Az ActiveMQ egy Java alapú megvalósítás, ami szinte mindent tud, amit egy ilyen üzenetsor megvalósítástól elvárhatunk. Klaszterezhető, JMS kompatibilis, támogatja a STOMP-ot (PHP, Python, stb. kompatibilis), ráadásul van hozzá egy Camel nevű valami, ahol DSL-ekkel leírt szabályok segítségével összekötögethetünk üzenet sorokat, újra rendezhetjük őket, broadcastolhatjuk az üzeneteket, stb., tehát konfigurálhatjuk az üzenet sort, és így különösebb programozás nélkül integrálhatjuk a komponenseket. A feature-öket tekintve nagyon szimpatikus megoldás, kérdés hogy mennyire erőforrás igényes.

A másik megoldás a MorbidQ ez Python-ban íródott, de STOMP kompatibilis, tehát ugyanúgy alkalmas heterogén komponensekből álló rendszer integrálására. Sokkal kevesebbet tud, mint az ActiveMQ, amire a honlapon is felhívják a figyelmet, hisz itt a lényeg az volt, hogy egy abszolút pehely súlyú megoldást nyújtsanak. Ez az erőforrás használat miatt lehet szimpatikus, de közelebbit nem tudok róla mondani, hisz nem próbáltam még ki, és nem hasonlítottam még össze az ActiveMQ-val.

Összefoglalva tehát ha a rendszerünk heterogén komponensekből épül fel, aszinkron üzenetkezelésre, erőforrás elosztásra van szükségünk (akár időben – soros végrehajtás, akár térben – klaszterezés), akkor ideális megoldás az üzenet sorok használata. Ilyen esetekben mindenképp érdemes számba venni ezek használatát, melyekből professzionális open source megoldások léteznek, mint pl. az ActiveMQ.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)
Categories: Tech Tags:

jQuery AJAX Form

május 17th, 2010 Nincsenek hozzászólások

Régóta keresek olyan egyszerű AJAX form megoldást, amit viszonylag fájdalom mentesen a szerver kód megváltoztatása nélkül integrálhatok a webes alkalmazásaimba. A neten többfajta megoldás fellelhető, de mindben közös, hogy az adatok szállítására valami speciális formátumot (pl. JSON) használnak, vagy valamilyen speciális szerver oldali függvénykönyvtárat (pl. XAJAX) igényelnek. Ezek jó megoldások, kímélik a sávszélességet, támogatják a szerver oldalról történő HTML manipulációt, stb., de igazából egyik sem tetszett igazán a szerver oldal “elcsúfítása” miatt. Nekem egyszerűen csak arra lett volna szükségem, hogy a submit gomb megnyomása után ne ugorjon a böngésző a lap elejére és ne kelljen adott esetben hosszú másodpercekig görgetni az egérrel, hogy visszamászunk a lap aljára, mindezt úgy, hogy ne kelljen a szerver oldali kódhoz nyúlni. Nem igazán érdekelt a sávszélesség kímélése, a kigenerálandó felületek számának csökkentése, egyszerűen csak az idegesítő oldalfrissítést akartam megkerülni. Az ember azt gondolná, hogy ez általános probléma és biztos van rá kész megoldás, mégis hosszú keresgélés után sem találtam ilyesmit, így hát úgy döntöttem lefejlesztem. Az eredmény egy néhány soros (jelen formájában 61 lazára formázott sor) JavaScript library lett, ami mostanra jócskán túlmutat eredeti célján.

Az alapötletet a JBoss Seam részét képző Ajax4jsf library adta. Itt szinte minden komponensnek van ajaxos változata, amely rendelkezik egy reRender attribútummal, ahol azt adhatjuk meg, hogy a komponens által végrehajtott metódust követően milyen id-jű mezőket kell frissíteni. Itt transzparens módon valósul meg az ajaxos működés, hisz nem JSON csomagok mászkálnak ide-oda, amikhez feldolgozó logika és nagy adag kliens oldali JavaScript kell, hanem HTML darabok, melyek generálását a keretrendszer oldja meg. Ez tehát egy olyasmi megoldás, amire nekem szükségem volt, a probléma csak az vele, hogy Java/JSF függő. Én egy sokkal általánosabb, keretrendszertől független megoldást szerettem volna (konkrétan PHP-ban akartam használni), lehetőleg minél kevesebb JavaScript-et felhasználva. Az igények, és az ötlet tehát már elég jól körvonalazódott, jöhetett a megvalósítás.

A JavaScript mentes megvalósításhoz a jQuery szinte adta magát. Ez egy un. “unobtrusive” JavaScript library, ami azt jelenti, hogy segítségével a JavaScript-et leválaszthatjuk a HTML kódról és CSS szelektorok segítségével “aggathatjuk” rá az eseménykezelőket az egyes elemekre, illetve módosíthatjuk azok attribútumait. Az egész ráadásul mindehhez egy böngészőfüggetlen programozói felületet ad. A lényeg tehát, hogy úgy szkriptelhetjük fel a lapot, hogy közben tiszta marad a HTML kód.

Így már majdnem minden adott volt, de kellett még egy kis ötlet amit a progress bar-os fájlfeltöltős JavaScript komponensektől kölcsönöztem. Itt az a trükk, hogy a form target-jét egy hidden iframe-be irányítják. Így a feltöltés elindul ugyan, de az oldal nem frissül. Ilyenkor a JavaScript egy másik szálon is kapcsolódik a szerverhez (a klasszikus XMLHttpRequest-el) és bizonyos időközönként lekérdezi a szervertől a képfeltöltés állapotát. Így képes feltöltés közben oldalfrissítés nélkül mozogni a progress bar.

Innen már csak össze kellett rakni a kódot. A jQuery alapú library létrehozza a rejtett iframe-et, kikeresi azokat a formokat ahol a form class attribútuma ajaxform, majd ezeknél beállítja a target-et és rárak egy kis submit scriptet is a formra. A formon belül egy rejtett input mezőben soroljuk fel azoknak az elemeknek az id-jét, amelyeket a submit gomb megnyomása után frissíteni kell. Mikor a felhasználó megnyomja a submit gombot, a kérés elmegy a szerver felé, az legenerálja az új oldalt, a submit script pedig visszamásolja a megadott id-vel rendelkező elemeket az eredeti HTML-be. Nem túl bonyolult dolog, a hozzá tartozó kód sem az, és tökéletesen megoldja a bejegyzés elején felvetett problémát, tehát a szerver oldali kód megváltoztatása nélkül valósul meg az oldal újratöltése nélküli AJAX-os működés. A megoldás ráadásul teljesen JavaScript mentes (csak a library-t kell betölteni). Mikor a kis programkönyvtár (a formázott kód kényelmesen elfér másfél képernyőn) elkészült, akkor döbbentem csak rá, hogy mennyire szép ez a megoldás, hiszen az eredeti célja mellett rengeteg lehetőség rejlik még benne.

Kezdjük ott, hogy az újratöltés nélküli frissítéssel egy csomó mágikusnak tűnő dolog nagyon egyszerűen, JavaScript nélkül megoldható. Gondoljunk például egy portál rendszerre, ahol adminisztrátorként belépve a cikkek alján egy módosítás gombot is látunk. A gombot megnyomva a szöveg “átváltozik” szerkesztővé, ahol módosíthatjuk a tartalmat, majd a változtatások elvégzését követően “visszaváltozik” tiszta szöveggé. Ilyesmihez általában komoly JavaScript-eket használnak kliens oldalon. De hasonló megoldás lehet egy popup, ami a gombot megnyomva ugrik fel, vagy egy nyitható zárható dinamikus (nem JavaScript-es) fa lista, dinamikus táblázatok, stb. Szinte az összes tipikus AJAX-os komponens megvalósítható kliens oldali JavaScript nélkül a szerver oldalon generálva.

A másik jópofa lehetőség, ami adja magát, hogy a szerver oldalon kiolvassuk a frissítendő id-ket (emlékezzünk, hogy ezeket egy hidden mezőben adtuk meg, ami természetesen a form elküldésekor átkerül a szerverhez), és egy olyan csonka html kódot generálunk, ami csak az id-kkel megadott részeket tartalmazza. A többi HTML kód generálása tulajdonképpen teljesen felesleges, hisz azok nem kerülnek vissza az eredeti kódba. Így tehát egy olyan megoldásunk van, ami képes ugyan a szerver kód megváltoztatása nélkül is működni, de lehetőséget ad arra is, hogy a szerver kód minimális módosításával sávszélesség és számítási kapacitás kímélő módon működjön, úgy mint más JSON alapú JavaScript igényes megoldások. Tulajdonképpen megfelelően kialakított HTML kód esetén (mindent CSS-ből formázunk, stb.) a mozgatott adattartalom mennyisége nem sokban tér el a JSON-ös változattól, ugyanakkor minimális változtatásra van szükség a szerver oldalon, a kliens oldalon pedig szinte semmire, ráadásul a működése teljesen JavaScript mentes. E mellett a megoldás keretrendszer független és alkalmazása valóban rendkívül egyszerű.

A Google Code-on létre is hoztam egy kis projektet a programkönyvtár számára, ami szerintem méltán kaphatja meg a “világ legkisebb AJAX library-je” címet.

A link: http://code.google.com/p/jqueryajaxform/

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)
Categories: Tech Tags:

Java Servlet-ek futási idejének limitálása 2.

Az előző bejegyzés óta kicsit utánanéztem a FastCGI működésének. Kíváncsi voltam, milyen lehetőségek vannak a halott process-ek kilövésére, stb. Tulajdonképpen a működési logika igen egyszerű. A FastCGI modul előre megadott mennyiségben forkolja a process-t, és ha kérés jön, egy éppen szabad process-nek adja az adatokat feldolgozásra. Beállíthatunk egy request időkorlátot, és ha ezt túllépi a végrehajtás, az adott process halott állapotba kerül. Ekkor azonban maga a process még bennmarad a memóriában. A FastCGI modul megadott időközönként körbenéz, hogy mi újság a process-ekkel, és a halottakat kilődözi, majd új process-ekre cseréli. Ez alapján kicsit elgondolkodtam, hogy talán nem is a Servlet környezet “FastCGI-re erőltetése” az üdvözítő megoldás, hiszen a fenti működési logika a szabvány megoldásokkal is megvalósítható.
Az új ötletem, hogy FastCGI helyett Jetty process-eket kellene futtatni. A Jetty egy pici, kompakt, flexibilis Servlet container, így valószínűleg nem fogyasztana többet, mint egy FastCGI-ra épített speciális változat. Az Apache alá mod_jk-val ugyanúgy be lehetne fésülni, mint a FastCGI-t, és a mod_jk loadbalancing lehetőségének hála, indíthatunk több példányt is ugyanúgy, mint FastCGI esetén. És ami a lényeg, megvalósítható egy FastCGI-hez hasonló gyilkoló mechanizmus is. Mikor egy Jetty process nem tud időben kiszolgálni egy kérést, az adatbázisba bejegyezi, hogy halott a státusza. Eztán a FastCGI-hez hasonlóan egy külső process bizonyos időközönként végigfésülné az adatbázist, és ha talál halott Jetty process-t, egyszerűen kilőné azt, majd új példányt indítana.
A megoldás előnye, hogy viszonylag kis ráfordítással megvalósítható, hiszen nem kell hozzá külön Servlet containert készíteni, ugyanakkor az alkalmazásonkénti több jetty processnek köszönhetően biztosított a magas rendelkezésre állás, valamint a végtelen ciklusok, és hasonló programozási hibákból adódó problémák is kivédhetőek, tehát a FastCGI-hez hasonló, de teljesen szabványos megoldás alakítható ki.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)
Categories: Tech Tags:

Java Servlet-ek futási idejének limitálása

április 22nd, 2010 2 hozzászólás

Már régóta keresek olyan megoldást Java-ban, mint PHP esetén a max_execution_time, amivel a Servlet-ek futási idejét lehetne korlátozni. Hosszú keresgélés után arra jutottam, hogy a problémának egyszerű frappáns megoldása nem létezik, ugyanis az alkalmazásszerverek szálakban futtatják a Servlet-eket, és mivel a szálak leállítása (Thread.stop) már jó ideje depricated, nincs olyan metódus, amivel kilőhetnénk egy szálat. Röviden tehát nincs értelmes megoldás arra, hogy kivédjünk egy Servlet-ben keletkező végtelen ciklust. Ugyanakkor van 1-2 áthidaló módszer, ami nem szép ugyan, de valamilyen módon megoldja a fenti problémát. Ezekből írnék le néhányat:

A legegyszerűbb megoldás, hogy a depricated megjelölés ellenére használjuk a stop metódust. Ez több szempontból is veszélyes. Először is ha jól tudom a depricated metódusok későbbi Java verziókból eltűnhetnek, így az alkalmazásunk Java verzióhoz lesz kötve. Ezen kívül a stop-nak vannak egyéb nem kívánatos hatásai is, nem véletlen, hogy depricated lett. Az a gond a stop-al, hogy ha megölünk egy szálat, bizonyos erőforrások lefoglalva maradhatnak. Tipikus példa, hogy ha létrehozunk egy átmeneti fájlt a szálban, majd kilőjük azt, az átmeneti fájl ottmarad. Ez mondjuk áthidalható oly módon, hogy nem engedünk ilyen erőforrásokat használni a szálban. Például fájlok helyett adatbázis használunk. Ez utóbbi esetben ugyanis megtehetjük, hogy a szálnak adunk egy adatbázis kapcsolatot, indítunk egy tranzakciót, és ha az idő lejárt, csinálunk egy rollback-et, vagy egyszerűen kirántjuk alóla a kapcsolatot (az adatbázis szerver jó eséllyel ez utóbbi esetben is rollback-el magától). Így nem marad inkonzisztens állapot. Tulajdonképpen egy servlet-en belül más külső erőforrást nagyon nem is használunk, tehát a fájlrendszer adatbázisra történő lecserélése szinte teljes egészében megoldja a problémánkat. Ezt amúgy is érdemes megfontolni, ugyanis a fájlrendszerrel ellentétben az adatbázis viszonylag egyszerűen klaszterezhető, így igény esetén könnyebb lesz több gépen szétkenni az alkalmazást. Ennek ellenére azért a Thread.stop függvény depricated mivolta kicsit kérdésessé teszi az egész eljárást.

A másik megoldás amit találtam, hogy a Servlet-ek kiszolgálását nem szálakban, hanem különálló process-ekben végezzük el. Ez kicsit hasonlít a CGI végrehajtáshoz, és a hátrányai is ugyanazok. Minden esetben újra inicializálni kell az egész környezetet, aminek jelentős overheadje van. A megoldás ugyanaz lehet, mint amit CGI esetén a FastCGI csinál. Elindítunk néhány Servlet kiszolgáló process-t, amit végrehajtás után újrahasznosítunk. Így nincs inicializálási overhead, és bár az erőforrásigény nagyobb (pl. minden process-nek külön heap kell), azért az esetek többségében elviselhető. A futási időben nem lesz különösebb változás, hiszen alacsony szinten a natív szálak és a process-ek közötti váltás hasonlóan történik. Ebben az esetben tehát úgy néz ki a dolog, hogy indítunk valamennyi servlet kiszolgáló process-t, és ha kérés jön, keresünk egy szabadot, lekezeltetjük a kérést, majd a felhasználónak visszadobjuk a választ. Ha a process túl sokat időzik a válaszadással (pl. végtelen ciklus miatt), egyszerűen kilőjük az adott process-t, létrehozunk egy újat, és minden megy tovább úgy, ahogy eddig. A kérdés már csak annyi, hogy milyen módon érdemes kilőni a process-t? Az egyik módszer, hogy egyszerűen kill-el kilőjük. Ami hatásos ugyan, de elég durva, hiszen a Servlet futtató környezetnek esélye sincs, hogy normálisan lezárja az erőforrásokat (pl. SQL kapcsolat lezárása). Ennél sokkal enyhébb, ha a kérés feldolgozását külön szálba indítjuk, és indítunk mellé egy timeout szálat, ami ha lejár, ellenőrzi, hogy volt-e eredménye a feldolgozásnak. Ha igen, visszaadja azt, ha nem, felszabadítja az erőforrásokat, és futtat egy System.exit()-et. Ezzel a megoldással tulajdonképpen belülről vesszük rá öngyilkosságra a túl sok erőforrást felhasználó process-t.

A fentiek alapján már nagyjából összeállt a fejemben az architektúra. Mivel általában így is – úgy is Apache-ot használunk a request-ek feldolgozására (pl. mod_jk-n keresztül), ezért célszerű ezzel legyártani a process-eket. Erre ideális megoldás lehet a FastCGI, ahol beállíthatjuk, hogy hány élő process legyen, és a webszerverrel történő kommunikáció is adott. Minden egyes Java process saját Servlet futtató környezettel rendelkezik. A lényeg annyi, hogy egy process egyetlen request feldolgozását végezze egyszerre. Ha jön egy kérés, a FastCGI mechanizmus kiosztja azt valamelyik process-nek, ami megpróbálja kiszolgálni a kérést. Ha a Servlet nem végez az adott időn belül, a process saját magát öli meg, amit a FastCGI elvileg kezel, tehát a halott process-t új változattal pótolja. A megoldás szépsége, hogy tulajdonképpen bármire általánosítható, tehát ugyanezt pl. meg lehet valósítani Python-ra is, így lesz egy időkorlátos Python futtatókörnyezetünk. A FastCGI-nak köszönhetően az inicializálást elég egyszer elvégezni, a process-en belül működik a connection pool-ing, vagy bármilyen más “újrahasznosító” technológia, így a végrehajtásnak nem lesz sokkal nagyobb az overhead-je, mint ha szálakkal dolgoznánk. Az egyetlen probléma a külön allokált heap, de ezzel lehet takarékoskodni, és ha jobban meggondoljuk, ez akár előny is lehet, hiszen egy felszálazott környezetben ha egyetlen szálnak elszáll a memória felhasználása, az az egész alkalmazás OutOfMemory-val történő lehalását eredményezi, egy ilyen rendszerben viszont minden végrehajtásnak külön memória korlátja van, így legrosszabb esetben is csak az aktuális request száll el.

Összességében tehát bár nem próbáltam még ki, de úgy érzem ez egy hatékony megoldás lehet biztonságos keretbe zárt Servletek futtatására, és egy nagy rendelkezésre állást biztosító, külső fejlesztők számára nyitott (a PHP-hoz hasonlóan megvalósítható rajta Java hosting, hisz a felhasználók nem tudják tönkretenni a futtatókörnyezetet) Google App Engine-hez hasonló rendszer kialakítására.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)
Categories: Tech Tags:

PHP fejlesztés Eclipse-el, XAMPP-al és XDebug-al

április 17th, 2010 1 hozzászólás

Bár alapvetően Java párti vagyok, weblapfejlesztések esetén mindig vissza-vissza tér a PHP. Nehéz tőle szabadulni, hisz ez a webhosting szolgáltatók által leginkább támogatott rendszer, és olyan pozitív tulajdonságokkal rendelkezik, mint pl. a futási idő maximalizálása (Java esetén máig nem találtam értelmes megoldást arra, hogy mondjuk egy esetleges végtelen ciklus esetén kiüssem az aktuálisan futó szálat). Ezzel szemben a Java típusos nyelv, és nagyon kellemesen lehet benne debug-olni, amit annyira megkönnyíti az ember dolgát, hogy e nélkül már nem is menne a fejlesztés. A legnagyobb gondom a PHP-vel tulajdonképpen pont ez utóbbi feature hiánya volt. Többször nekiestem már a probléma megoldásának, de általában feladtam, mert mindig valami gigszer csúszott a dologba. Ma úgy döntöttem, bepróbálkozok még egyszer, és végre sikerrel jártam. Sikerült egy nagyon kellemes PHP fejlesztőkörnyezetet összelőnöm XAMPP, Eclipse és XDebug segítségével. Remélem ez a kis írás sokaknak segít, hogy hozzám hasonlóan kényelmes, debugolható (!) fejlesztőkörnyezetet állítsanak össze.

A dolog első lépése a XAMPP letöltése. A XAMPP egy összecsomagolt mini fejlesztőeszköz, ami minden szükséges összetevőt tartalmaz egy LAMP fejlesztéshez. Van benne Apache, MySQL, PHP, PhpMyAdmin, és mindez pöccre összelőve. Csak el kell indítgatni a szolgáltatásokat, és már írhatjuk is a PHP kódot. Mindenkinek csak ajánlani tudom, ennél jobb fejlesztőkörnyezettel Windows-ra még nem találkoztam. Az alap igényeket a XAMPP Lite is kielégíti, de érdemes a teljes XAMPP-ot letölteni, hiszen az tartalmazza az xdebug-ot.

Ha megvan a XAMPP, a következő lépés az XDebug konfigurálása. Ehhez kicsit módosítani kell a XAMPP-ban található php.ini-t. Az XDebug-hoz szükséges sorok bent vannak, csak ki kell szedni a komment jeleket, és átírni a paramétereket. A következő beállítások kellenek az XDebug bekapcsolásához (persze az elérési utak az adott XAMPP installációnak megfelelően legyenek megadva):

zend_extension = “D:\progs\xampp\php\ext\php_xdebug.dll”

zend_extension_ts=”D:\progs\xampp\php\ext\php_xdebug.dll”

xdebug.remote_enable = 1

xdebug.remote_handler = “dbgp”

xdebug.remote_host = “localhost”

xdebug.remote_port = 9000

Ha mindent jól csináltunk, akkor az apache újraindítása után a phpinfo-ban megtaláljuk az xdebug-ra vonatkozó részeket. Maga a debuger úgy működik, hogy ha a php értelmező a webszervertől ?XDEBUG_SESSION_START=…&KEY=… paramétereket kap, megpróbál kapcsolódni a 9000-es portra, és ezen keresztül teszi lehetővé a program futásának követését. Többfajta kliens is létezik, de a legjobb az Eclipse fejlesztőrendszerbe épített változat, hiszen az Eclipse fejlesztőkörnyezetnek sem utolsó. Ehhez töltsük le az Eclipse PHP-hez kialakított változatát az http://eclipse.org/downloads/ címről. Ez eclipse telepítése után indításkor válasszuk workspace-nek a XAMPP htdocs könyvtárát, így sok későbbi problémától kímélhetjük meg magunkat. Ezt követően a Window/Preferences/PHP/Debug részben válasszuk ki az XDebug-ot. Tulajdonképpen ennyi az egész. Innentől kezdve ha valamelyik php fájlra jobb gombot nyomunk, és kiválasztjuk a Debug As…/Web page opciót, a debugger elindul, és használhatjuk a jól bevált eszközöket. Brakepointokat helyezhetünk el, watch-olhatjuk a változókat, stb. A dolog gyönyörűen működik, és végre elfelejthetjük a var_dump-okkal teletűzdelt PHP kódokat.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)
Categories: Tech Tags:

JBoss POJO Cache mint adatbázis

február 16th, 2010 1 hozzászólás

Az memória alapú adatbázisok kapcsán kicsit utána néztem a postban felvetett megoldásnak, vagyis hogy a JBoss POJO Cache-re építve lehetne-e memória alapú adatbázist készíteni. A POJO Cache dokumentációja alapján elvileg minden adott ehhez. Ahogyan már írtam, clusteres kialakítás esetén a POJO cache önmagában képes a benne tárolt objektum fa transzparens replikálására, méghozzá úgy, hogy csak a változásokat szórja a rendszerben. A cache ezen kívül kezeli az objektum referenciákat, és még tranzakció támogatást is nyújt, tehát valóban minden rendelkezésre áll ahhoz, hogy adatbázis rétegként használjuk. Létezik egy mechanizmus, aminek segítségével a cache-ből kikerülő elemeket perzisztens tárba menthetjük, így a passziválás is megoldott. Ugyanígy létezik mechanizmus a változások mentésére, valamint a cache állapotának perzisztens tárolóból történő visszaállítására. A JBoss POJO Cache tehát elvileg könnyen alkalmassá tehető arra, hogy memória alapú adatbázisként működjön, sőt sokkal egyszerűbben, mint gondoltam. E ellett olyan feture-ök is eleve adottak, mint például a tranzakció kezelés. Egyedül az volt csak fura, hogy hiába kerestem a neten, nem találtam példát ilyen megvalósításra, pedig szinte adja magát a dolog. Már csak egy projekt kellene, ahol a gyakorlatban is ki lehet próbálni a fentieket …

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Memória alapú adatbázisok

február 15th, 2010 Nincsenek hozzászólások

A napokban ismertem meg egy új adatbázis szervezési filozófiát, az Object Prevalence -t, amit jobb híján memória alapú adatbázisnak fordítottam (tudom, hogy a szó szerinti fordításnak semmi köze ehhez, de ez adja vissza legjobban magyarul, hogy miről is van szó). A filozófia alapgondolata, hogy napjainkban a memória nem túl drága erőforrás, és megfelelő mennyiségben rendelkezésre is áll ahhoz, hogy egy rendszer teljes adatbázisát ott tároljuk. Gondoljunk csak bele, ha mondjuk egy felhasználó tárolása 5K memóriát igényel (és 5000 karakterbe aztán tényleg rengeteg adat belefér), akkor 1000 felhasználó mindössze 5Mb-ot, 10 000 pedig 50Mb-ot igényel. 10 000 felhasználó már egész jelentősnek mondható, ugyanakkor 50 Mb a jelenlegi RAM méretek mellett elenyésző. Ez alapján szinte adja magát a gondolat, hogy a teljes adatbázist tartsuk a memóriában, célszerűen az adott programozási nyelv jól megszokott eszközeivel (pl. Java esetén sima Map-ek és List-ek). Kicsit olyan érzésem van a dologgal kapcsolatban, mintha a relációs adatbázis kezelők csak mindössze a nyakunkon maradtak volna azokból az időkből, mikor még a memória és a tároló kapacitás drága volt.

Más szempontból vizsgálva azt is mondhatjuk, hogy a memóriába ágyazott adatbázisok a jelenlegi rendszerek optimalizálásának logikus következő lépései. Gondoljunk csak egy általános vállalati rendszerre, ahol az adatbázist valamilyen ORM rétegen keresztül (pl. Hibernate) érjük el. Egy entitás objektum módosítása esetén módosítjuk a memóriában lévő lokális változatot, amit az ORM engine SQL utasításokra alakít, átpaszírozza őket egy socketen, ott az adatbázis szerver értelmezi az SQL utasításokat, és módosítja a winchesteren található fájlokat. Ha adatot olvasunk, ugyanez megy visszafelé. Az az ironikus a dologban, hogy a winchesteren lévő adatbázis fájlokat a gyakori használat miatt az operációs rendszer jó eséllyel felcache-eli a memóriába, így végső soron ugyanúgy a memóriából dolgozunk, csak ehhez a szükséges erőforrások sokszorosát használjuk el. Memória tekintetében rossz esetben legalább 2x megvan az adat (az ORM által kezelt memória reprezentáció, valamint az SQL adatbázis felcache-elt része), és itt még nem beszéltünk a közbe iktatott mindenféle cache-ekről, amit az adattáblák és a Java alkalmazás közé pakolunk, hogy gyorsítsuk az elérést. Számítási erőforrást tekintve megint csak elég rossz a helyzet, hiszen az adatok módosítása egy rakás SQL-t eredményez, amit az adatbázis szervernek értelmeznie kell, majd végrehajtania a változásokat, újraindexelni a táblákat, stb. A memória alapú adatbázisok segítségével ezek a felesleges köztes lépések kiküszöbölhetőek.

Jelenleg két implementációt találtam Java nyelven a memóriába ágyazott adatbázisokra. Az egyik a Prevayler a másik pedig a valamivel okosabbnak tűnő Space4j.

Persze az első kérdés, ami felmerül, hogy ha minden adatot a memóriában tartunk, mi történik egy esetleges rendszer leállás/áramszünet, stb. esetén. A Prevlayer/Space4j megoldása a problémára, hogy minden adatmanipuláló műveletet un. Command-okba csomagolunk és a memória objektumok manipulálását csak és kizárólag ezeken keresztül végezhetjük. Minden Command végrehajtását log-oljuk, így ha leáll a rendszer, nincs gond, hiszen a Command-okat újra lefuttatva visszakapjuk az eredeti állapotot. A gondolat maga nem új keletű. Így működnek az adatbázis rendszerek tranzakciói, vagy éppen a HSQLDB, ami egy ugyancsak memóriában működő, de SQL alapú adatbázis. Hogy a log fájl ne nőjön túl nagyra, bizonyos időközönként a rendszer csinál egy memória snapshot-ot, amikor a teljes állapotot lemezre menti. Ez kicsit erőforrás igényesebb művelet, de általában ez is viszonylag gyorsan megtörténik, és csak ritkán kerül rá sor.  Egy ilyen adatbázisban tehát az olvasás extrém gyorsan történik, hiszen egyszerű memória műveletekről van szó, és a módosítás is nagyságrendekkel gyorsabb, mint egy relációs adatbázis esetén, hiszen mindössze csak a Command-ot kell serializálni, és letenni a log-ba, nem kell SQL-eket értelmezni, indexeket karbantartani, fájlokat átrendezni, stb.

A következő kérdés, ami felmerül egy ilyen rendszerrel kapcsolatban, hogy mi van, ha valahogy mégis olyan hatalmasra nőne az adatbázis, hogy nem fér el a memóriában, esetleg másnak is kell a memória. A Space4j-ben ennek megoldására létezik egy mechanizmus, ami a nem használt adatokat a lemezre “passziválja”. Egy adatbázis esetén valószínűleg sok ilyen objektum van, amire épp aktuálisan nincs szükség. A mechanizmus hasonló az operációs rendszerek virtuális memória kezeléséhez, oly annyira, hogy talán nem is érdemes ezzel alkalmazás szinten foglalkozni. Bár gyakorlati tapasztalatom nincs, valószínűleg egy linux rendszer esetén elég lenne annyi, hogy megfelelően nagy swap területet hozunk létre. Bár nem tudom, hogy a kernelnél hol a határ, de ha jól tudom, a mai modern processzorok  legalább 4 Tb memória megcímzésére képesek. Tehát elvileg nem tiltja semmi, hogy akár Tb-os méretű swap használatával gigantikus virtuális memóriát hozzunk létre, amiben már akármilyen adatbázis kényelmesen elfér. Ráadásul az operációs rendszer natív virtuális memória kezelő mechanizmusa biztosan nagyságrendekkel gyorsabban és hatékonyabban működik, mint egy Java-ban programozott megoldás.

A memória alapú adatbázisok működése tehát egyszerű, elegáns, gyors, és erőforrás takarékos, ugyanakkor szinte mindenre képesek, amire egy relációs adatbázis. Például nagy adathalmazok esetén ugyanúgy definiálhatunk indexeket, de itt a megoldás jellegéből adódóan nem kell bonyolult index struktúrákban gondolkodni, elég egy bináris fa, amit az egyetem első félévében minden programozó tanonc fejébe belevernek.

Bár még a gyakorlati tapasztalatom nincs ezekkel a rendszerekkel, az látszik, hogy legnagyobb hátrányuk a Command-ok viszonylagos bonyolultsága lehet, ezekben a rendszerekben ugyanis a Command-ok a módosítás atomi műveletei, amelyek működésébe a rendszer nem lát bele. Az egyetlen dolog, amire a rendszer képes, hogy végrehajtsa a Command-okat. Minden adatellenőrzést, ütközés figyelést, stb. a Command-on belül nekünk kell leprogramozni, ezekhez a rendszer nem nyújt semmilyen támpontot. A másik dolog, ami csak nagyon problematikusan oldható meg, az a konkurens tranzakciók használata. Ez csak oly módon kivitelezhető, hogy másolatot készítünk a tranzakcióban részt vevő objektumokról, majd a tranzakció végeztével a módosításokat végrehajtjuk a memóriában lévő globális objektumokon. A másolást nem tudja nekünk transzparens módon elvégezni a rendszer, hiszen nem lát bele az atomi Command-ok működésébe, így azt sem láthatja, hogy azok milyen adatokat módosítanak. Így az egyetlen lehetőségünk, hogy leprogramozzuk ezeket a másolásokat.

Ami még nagy előnye a rendszernek, hogy nagyon egyszerűen clusterezhető. Minden cluster elem rendelkezik egy saját objektum fával, és bármelyik rendszerben valamilyen módosítás történik az adatbázison, egyszerűen broadcast-olnia kell a módosítást végző command-ot. Persze ilyen elosztott rendszerben a command-okat érdemes timestamp-el ellátni, a hálózati lag-ból eredő elcsúszások kiküszöbölésére (a Command-ok megfelelő sorrendben történő végrehajtása nagyon fontos). Maga a megoldás (módosítások broadcastolása a rendszerben) megint csak nem új keletű. Tulajdonképpen az összes clusterezhető cache (memcached, ehcache, JBossCache, stb.) így működik. Ha valahol változik valami, azt jelszik a többi szerver felé, így tartva konzisztensen a globális állapotot.

Tulajdonképpen a clusterezés gondolatán elindulva jutott eszembe, hogy a Cluster Cache-ek filozófiáját és a memória alapú adatbázisok filozófiáját ötvözve létre lehetne hozni valami perzisztens cache szerű dolgot, ami mentes lenne a Command-ok bonyolultságából eredő hibáktól. A rendszer alapja a JBossCache, vagy valamilyen ahhoz hasonló megoldás lehetne. A JBoss POJO Cache ugyanis tud valami nagyon ügyeset. Komplett Java objektum fákat tárolhatunk benne, mégis gyorsan képes szinkronizálni a cluster egyes elemeit. Ezt úgy éri el, hogy mindenféle proxy-k (és talán AOP) segítségével figyeli, hogy a cache-ben tárolt adatok mikor változnak, és csak a fa változásait küldi szét a többi szervernek. Ez nagyon hasonlít egy cluster-be kötött memória alapú adatbázis működéséhez, ahol a command-ok a JBossCache-ben tárolt objektumok változásai. Nem kellene tehát más tenni, mint a cluster cache-t kiegészíteni egy olyan mechanizmussal, amely folyamatosan log-olja a műveleteket, és néha snapshot-ot készít az aktuális állapotról. Ezt neveztem el én perzisztens cache-nek. Egy ilyen megoldásban nem lenne szükség command-ok írására, így az adatbázis kezelés valóban mindössze memóriában tárolt Java objektumok használatából állna, a rendszer valóban teljesen transzparens lenne. Ami a command-ok egyéb funkcióját illeti (adat ellenőrzés, indexelés, stb.), azt AOP segítségével aggathatnánk rá az adott objektumokra, így megőrizve a rendszer transzparenciáját.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

JBoss hibakeresés

február 15th, 2010 Nincsenek hozzászólások

Mostanában elég sokat szívtunk néhány hibával egy JBoss-on futó rendszerben. A legtöbb hiba persze fejlesztéskor rögtön szemet szúr, vagy ha mégsem, úgy a log alapján hamar megtalálható az oka, van azonban néhány elég nehezen felderíthető. A legutálatosabb, mikor a nem optimális kód, vagy egy rejtett (akár több metódus híváson keresztül ívelő) végtelen ciklus annyira leterheli a rendszert, hogy az képtelen válaszolni (kvázi DoS-olja azt). PHP esetén van erre egy nagyon egyszerű mechanizmus, ami figyeli, hogy mi mennyi ideig fut, és ha túl sok idő telt el, egyszerűen kilövi. Nem is csoda, hogy a hosting szolgáltatók körében a PHP a leggyakoribb, hiszen erre könnyen lehet biztonságos hosting szolgáltatást építeni (a jogosultságok, memória limitek, idő limitek jó beállításával kiküszöbölhető, hogy a felhasználó megölje a szervert). Ilyen mechanizmust nem találtam JBoss-hoz (Tomcat-hez, mert valójában az intézi a web-es dolgokat), így marad a szerver újraindítása, és a log fájlok bújása.

Az ilyen hibák felderítésére a legegyszerűbb módszer, hogy a JBoss PID-re kiadunk egy kill -3 -at, aminek hatására a Java VM a log-ba hányja az aktuális szálak állapotát stack trace-el. Ilyen kill -3 -ból érdemes többet is nyomni néhány másodperces eltéréssel, hogy később ne csak az utolsó állapotot lássuk a szálaknak, hanem az egyes szálak működését folyamatában (pl. egy több metódusos végtelen ciklust így lehet leginkább kiszűrni). A baj az ilyen thread dump-okkal az, hogy a processzor használatot nem látjuk belőlük, így nem látszik, hogy pontosan melyik szálak próbálják megenni a processzort. Hogy ezt megtudjuk, adjunk ki egy ps -L auxH parancsot, ami az egyes szálak processzorhasználatát mutatja. A log-ot, és a ps eredményét az LWP/nid köti össze. A ps-ben látható LWP a szál egyedi azonosítója, amit hexadecimális formában nid néven a thread dumpban is megtalálunk. Tehát nincs más dolgunk, mint megkeresni a kiugró, extrém magas processzor használatot mutató szálakat, az ezekhez tartozó LWP-ket hexadecimálisra váltani, majd belekeresni a logban, hogy a hozzá tartozó szál mit csinál. Ezzel a módszerrel viszonylag egyszerűen megtalálhatjuk a kód kritikus részeit.

Annak idején én külföldi blog-ok alapján szedtem össze ezt a módszert, így gondoltam megosztom magyar nyelven is, hátha mások is hasznát veszik.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)