Kliens-szerver architektúra

Egy web programozónak talán nem is kell mással foglalkoznia, mint a kliens szerver arhitektúrával, hisz valójában neki ez a foglalkozása. Vagy a kliens oldalt programozza, különboző lekéréseket fogalmazván meg, vagy a szerver oldalon az ő programja fogadja a kliens által megfogalmazott lekéréseket. Hogy még tisztább vizet öntsünk a programozó poharába, bemútatjuk az elméleti alapját ennek a rendszernek, ezzel is remélvén hogy sok olyan dolgot fogunk letisztázni, ami eddig nem, vagy csak halványan volt világos valaki számára.

Általános dolgok

Az Internet és főképpen a Web rohamos terjedésével napjainkra mindenki számára természetessé váltak az ún. kliens-szerver rendszerek, még ha nem is mindig gondolunk bele a háttérben zajló folyamatokba. A “klasszikus” Web az ún. kétlépcsős (2 tiers) rendszerek példája. A kliens oldalról a Web böngésző kérést juttat el a kiszolgálóhoz, aki erre válaszol. A számítási modell nagyon egyszerű, de mégis nagy előnyöket rejt magában: lehetővé teszi központi erőforrások szabályozott, távoli felhasználását, feladatmegosztást az ügyfél és a kiszolgáló között. Elegendően “intelligens” kiszolgáló rengeteg feldolgozási műveletet maga végezhet el, példa rá a Web böngészőben a HTML lapok megjelenítése, amely a multimédiát, 3D (VRML) elemeket tartalmazó lapok esetén nem csekély feladat. A kliens-szerver rendszereket a közöttük alkalmazott kommunikációs protokoll fogja össze, például szigorú értelemben akkor beszélhetünk Web-ről, ha a kommunikáció az Internet TCP szállítási rétegére  épülő HTTP protokoll segítségével bonyolódik.

A Web terjedésével a böngésző és a kiszolgáló közé fokozatosan kiegészítő hardver és/vagy szoftver elemek tolakodtak. Ezek egy része biztonsági célokat szolgál, például az ún. tűzfalak (firewall), illetve az ezeken keresztüli információcserét lehetővé tevő átjárók (gateway) és “megbízott” (proxy) kiszolgálók. A megbízott kiszolgálók átmeneti tárolással a hálózati sávszélesség korlátait is igyekezhetnek kompenzálni.

Ezen köztes berendezések a Web rendszerek létrehozói, az ún. tartalomszolgáltatók, Web programozók számára nem jelentettek külön problémát, hiszen a fenti funkciók helyes működésük esetén mind a kliens-, mind a szerver oldal számára láthatatlanok maradtak. Viszont hamar felmerült az igény, hogy a Web szerverek a statikus, állományokban tárolt információk HTML lapok mellett dinamikus, a kérés beérkeztekor előállított lapokat is visszaküldhessenek. A dinamikus információk forrását hívhatjuk a szó általános vagy gyakran konkrét értelmében adatbázisnak. Sőt az a kívánatos, ha az adatokat ténylegesen adatbázisban tároljuk, hiszen így sok fontos problémára pl. hozzáférési jogok szabályozása, konkurens hozzáférések vezérlésére, hatékony lekérdezés, mentés kész megoldásokat kaphatunk. 

A kliens-szerver architektúrának a legfontosabb alkalmazása az adatbázisok területén észlelhető. A különböző alkalmazásokhoz szükséges adatokat egy szerveren tárolják, az alkalmazás adatkérése és futása pedig egy úgynevezett kliens-gépről történik.

Feldolgozás és felhasználói interfész

hálózat

Adatbázis módosító program

 

A kliens-szerver achitektúrában azt a gépet, amely a felhasználóval kommunikál front-end-nek hívjuk, azt amelyik a háttérben az adatbázis műveleteket végzi back-end-nek. A modern adatbázismotoroknál a kettő között biztonsági hálózatot hozhatunk létre titkosítás segítségével. Mivelhogy az adatbázishoz csak a kliens gépről lehet hozzáférni különböző biztonsági szinteket lehet bevezetni a kliens gépnél ülő felhasználó jogai alapján.

A modern adatbázisszervereknél a következőképpen van a megosztás: az adatbázisszerveren van az adatbázis és a módosító program is, a kliens gépen van az interfész és a feldolgozás. A két gép között kell legyen egy hálózat is. A kliens gép kéréseket továbbít a hálózaton keresztül az adatbázisszervernek, melyekre eredményül adatokat kap. Ezeket feldolgozza és az interfészen keresztül közli. Előnye, hogy csak kérések és eredmények közlekednek, tehát elég minimális az adatforgalom.

A három lépcsős hozzáférésű adatbázis esetén a program adott protokollon keresztül egy középső szolgáltató réteggel kommunikál. A felhasználó gépén csak az interfész fut, a középső réteg értelmezi és átalakítja a programtól kapott parancsokat, majd továbbítja az adatbáziskezelő rendszerhez. A lekérdezési eredményeket szintén a szolgáltató rétegen keresztül kapja meg. Ezt a következőképpen vázolhatjuk:

 

Front-end (kliens)

 

Back-end (szerver)

1. lekérdezi az adatokat

hálózat

2. válaszol a kérdésre

4. felhasználja a választ

 

3. viszzaküldi a választ

Ez a 3- vagy többlépcsős rendszer, ahol az ügyfél (Web böngésző) és az adatbázis szerver közé egy kibővített funkciójú Web-, általános elnevezéssel alkalmazás-szerver kerül. Ennek az elrendezésnek a dinamikus lapok előállításán túl egyéb előnyei is vannak, például:

o                    a feladat-specifikus algoritmusok központi fejlesztése, tárolása: nem kell minden ügyfélben azonos feladatokat megoldani;

o                    az alkalmazás szerver eltakarja az ügyfelek elől a felhasznált  adatbázisok konkrét típusát, esetleg egyidejűleg több, heterogén technológiájú adatbázist kezelhet, lehetőséget nyújt elosztott tranzakciók megvalósítására;

o                    az adatbázis illetéktelen hozzáférések előli elrejtése: az alkalmazás szerver tipikusan a tűzfal környékére magára a tűzfalat megvalósító gépre kerül, így a külvilág közvetlenül csak ezt a kiszolgálót éri el, az adatbázisokhoz csak az alkalmazás szerver férhet hozzá;

o                    teljesítménynövekedés, hiszen a feladatot több számítógép között osztottuk fel, cseles programozási technológiákat használva akár dinamikusan allokálhatunk közbülső feladat-specifikus kiszolgálókat a terhelések enyhítésére;

o                    egyszerűbb fejlesztés: a megoldás jobban particionált, szabadabban válogathatunk a programozási nyelvek, könyvtárak, protokollok között.

A “hagyományos” Web kiszolgálók képesek a fenti programozási modell megvalósítására. Itt a kliens egy “egyszerű” Web böngésző, amely a HTTP protokoll segítségével, jobbára HTML formájú lapokat olvas a szerverről. A szerver az ún. CGI (Common Gateway Interface) segítségével az egyes kérések kiszolgálására elindíthat tetszőleges programokat, amelyek megvalósítják a feladat-specifikus logikát, ad-hoc módon kommunikálva az adatbázis(ok)kal. Természetesen az adatbázisok egyszerűbb esetben nem feltétlenül másik számítógépen futnak, sőt gyakran maguk a CGI programok valósítják meg az adattárolási, hozzáférési funkciókat.

A fenti modellnek a szerver oldalán komoly, a teljesítményt jelentősen csökkentő problémája maga a CGI mechanizmus: a CGI programok elindítása, szerverrel történő kommunikációja nagyon lassú, nagy CPU és tárigényű. Igaz, hogy a korszerű Web kiszolgálók különböző programozási trükkökkel szerver dinamikus bővítésével, szerver oldali programkönyvtárakkal (server-side API, pl. Netscape, Microsoft), a CGI-nél lényegesen gyorsabb, hatékonyabb program-hívási mechanizmusokkal (pl. Oracle “kazettái”) jelentősen javítanak a CGI hatékonyságán, ám 2 alapvető korláton nem tudnak túllépni:

o                    a HTTP protokoll legalábbis az elterjedt 1.0-ás változat esetén egyszerű, állapotmentes kommunikációt biztosít, a hálózati kapcsolata minden kérés-válasz után lebomlik, a protokoll egyébként sem hatékony;

o                    a HTML lapleíró nyelv, minden új bővítése ellenére korlátokat jelent a kliens oldalon az információ, kezelői felület megjelenésének formájában, bonyolultságában.

Háromrétegű alkalmazások

A háromrétegű alkalmazások feltételezik, hogy az általuk implementált ügyviteli szabályok értékesek és esetleg szükség lesz rájuk más rendszerekkel való kölcsönös műveleteknél is. A háromrétegű architektúra felosztja az alkalmazást három különálló rétegre: adatkezelésre, ügyviteli logikára és felhasználói megjelenítésre, mindegyiket a saját céljaival és tervezési megszorításaival egyetemben.

A legalsó réteg kezeli az adattárolást. Az adatokat a lehető legnyersebb formában kell tárolni. Nincsenek feltételezések, hogyan kell az adatokat feldolgozni, vagy hogy milyen műveleteket kell e rétegben az adatokon végrehajtani.

A második, logikai réteg implementálja az alkalmazás ügyviteli szabályait. E réteg nemt artalmaz feltételezéseket, hogyan tárolódik az adat. Az adatrétegtől egyszerűen elvárja, hogy adjon egy általános hozzáférési módot a nyers adatokhoz. A logikai réteg értéket ad a nyers adatokhoz azáltal, hogy alkalmazza rájuk az ügyviteli szabályokat és a harmadik réteg rendelkezésére bocsátja őket.

A harmadik réteg a felhasználói interfészt implementálja. Tudja, hogyan öntse formába és jelenítse meg a logikai rétegtől jövő adatokat a kliens készülékének megfelelő módon. Az interfész réteg biztosítja a felhasználó hozzáférését a logikai réteg olyan szolgáltatásaihoz is, mint a lekérdezés és az aktualizálás. A felhasználói interfész réteg sosem kommunikál közvetlenül az adatkezelő réteggel, és sohasem végez értéknövelő műveleteket az adatokon. E két funkció mindegyike teljesen a logikai rétegtől függ.

Jóllehet, a háromrétegű architektúra csak a kliens/szerver kis kiterjesztésének látszik  van egy alig észrevehető, kritikus különbség. A GUI objektumok lehetséges kivételével, az egyes rétegeket alkotó komponensek a feladatukat úgy végzik, hogy azokról nem feltételezik, hogy bármilyen alkalmazás bármilyen részét képeznék. Alkalmazások csak úgy léteznek, mint komponensek együttműködő csoportjai, és mindegyik komponens egyidejűleg sok különböző alkalmazásnak lehet a része.

A háromrétegű architektúra erejét nagymértékben a szemléletváltás adja: komponensek, mint alkalmazások elválaszthatatlan részei, szemben az önállóan létező komponensekkel, melyek alkalmazásoknak szolgáltatásokat tudnak nyújtani. Mivel az alkotórészek önálló szolgáltatóként vannak megtervezve, nem egy alkalmazás beágyazott részeiként, egyszerre lehetnek mindezeknek az alkalmazásoknak a részei.

A háromrétegű architektúra először az 1990-es évek elején lépett az IT világba. Azóta voltak viták arról, hogy valóban csak három rétegből állnak-e. Egyes szerzők úgy érvelnek, hogy az adat, a logikai és prezentációs rétegek különböző komponenseinek teljes elszigeteléséhez interfész rétegek kellenek az adat- és logikai rétegek, valamint a logikai és prezentációs rétegek között. E két réteg hozzáadása az ötrétegű architektúrát eredményezi. Mások szerint minden egyes réteg sok alrétegre bontható, melyek mindegyike magasabb szintű funkciókat nyújt, mint az alatta fekvő alréteg. Ez a struktúratípus az N-rétegű architektúra.  Lehet, hogy ezek a viták akadémiai értelemben érdekesek, annak a kérdésnek, hogy az adatszolgáltatási objektumok egy külön réteget alkotnak-e, vagy pedig egyenrangú társai az RDBMS-nek egyetlen rétegen belül, legfeljebb filozófiai jelentése van. A fontos az, hogy az ügyviteli logikát az RDBMS-től elszigeteli egy sor szolgáltatás, és  hogy e szolgáltatások az adatfolyam értékét növelik; nem egyszerűen csak közbenső réteget képviselnek, amely a nyers SQL kéréseket továbbítja az RDBMS-nek.

A három réteg előnyei

Azáltal, hogy az ügyviteli folyamatokat kifejezetten értékes erőforrásként ismeri el, és külön tárolóhelyről gondoskodik az e folyamatokat implementáló logikai programok részére, a háromrétegű architektúra sok olyan problémát oldott meg, amivel a kétrétegű kliens/szerver architektúra logikai monolitjei nem tudtak megbirkózni. Ezért a háromrétegű architektúrának sok előnye van az egyszerűbb kliens/szerver architektúrával szemben.

1.) Mozgékony szoftver

A háromrétegű architektúrát rugalmas és könnyen módosítható rendszerek létrehozására lehet használni. Egy olyan világban, amelyikben az informatikát egyre inkább stratégiai fegyverként használják a versenyben maradásért folyó harcban, nagy igény van a mozgékony szoftverre. A háromrétegű architektúra több lehetőséget nyújt a mozgékony szoftverre. Először is, azáltal, hogy a szoftverkomponenseket úgy tekinti, mint önálló adatforrásokat, szolgáltatásnyújtókat és szolgáltatásfogyasztókat (az adat, logikai és prezentációs rétegeknek megfelelően), a háromrétegű architektúra újrafelhasználható részekből álló szoftver infrastruktúrát alkot. Ez az újrafelhasználás nemcsak meggyorsítja a fejlesztést azáltal, hogy csökkenti a minden új projekthez írandó új kód mennyiségét, hanem a rendszer általában jobb minőségű lesz. Mivel az alkotóelemek más alkalmazásokban már üzemszerűen futottak, alaposabb hibajavításon mentek keresztül, mint egy új kód, melyet egyetlen projekthez írtak.

Azáltal, hogy egy alkalmazás koncepcióját elválasztja az implementáló komponensektől, a háromrétegű architektúra karbantartása és aktualizálása is sokkal könnyebb. Mivel az architektúrán belül minden komponensnek egyedi funkciója van, mely egyetlen másikban sem ismétlődik, a hibák helyhez-kötöttebbek. Ez azt jelenti, hogy egy hibát csak egyszer kell kijavítani, egyetlen komponensben. Emiatt csökken egy rendszer üzemben tartásához szükséges karbantartási ráfordítás, és kiküszöbölődik a rendszeren belüli verziókülönbségek veszélye. Azt is jelenti, hogy új ajánlatok tehetők néhány komponens egyszeri módosításával, vagy új komponensek hozzáadásával, nem pedig ugyanezen módosítás elvégzése mindegyik, a rendszerben lévő modulmásolaton.

2.) Java alkalmazási komponensek

A komponensalapú szoftver újrafelhasználás több, mint maguknak a komponenseknek az előállítása. A komponenseknek azon a kiválasztott platformon is rendelkezésre kell állniuk, amelyen a projektet üzembe kell állítani, mint ahogyan annak a környezetnek is, melyben a komponensek futnak.  Ez bizonyítottan az újrafelhasználás egyik majdnem leküzdhetetlen akadálya. Ha a szükséges komponenseket egyik platformról egy másikra kell átültetni, vagy pedig az adatbázis, vagy más, a futásukhoz szükséges környezet az új platformon nem létezik, ezek a kész komponensek a fejlesztő számára nem sokat érnek. A Java platform segíti e probléma megoldását. A Java komponensek bármilyen platformon futnak átültetés vagy újrakompilálás nélkül. A komponensek kölcsönhatását és tartalmát leíró JavaBeans modell a platform szabványos része és garantáltan az új platformon is jelen van. Végül, olyan szervezeti szolgáltatások, mint az Enterprise JavaBeans és a szervletek, széles körben kerültek implementálásra kész termékekben, lehetővé téve a fejlesztő számára, hogy kihasználja magasabb szintű alkalmazási környezetek előnyeit anélkül, hogy egyetlen szállítóhoz kötné az alkalmazást.

c.) Az összekötési probléma

A háromrétegű architektúrában az összekötési probléma azáltal oldódik meg, hogy a nyers adatforrások bármelyik más alkalmazás rendelkezésére állnak. Így nemcsak az ügyviteli logikát használhatjuk fel sok alkalmazásban, melyeknek mindegyike külön interfésszel bír, hanem maguk az adatok is felhasználhatók sok különböző szabályrendszerben, sok különböző alkalmazásban. Alkalmazásfüggetlen adatforrásokkal rendelkező háromrétegű környezetben nincs szükség külön adatkinyerő programokra, hogy az adatokat több alkalmazás is használhassa.

d.) Elosztott rendszerek kezelése

Ha egy alkalmazásnak egy új verziója kerül forgalomba, amely valamilyen új terméket vagy szolgáltatást implementál, de amelynek üzemnbeállításához mind a szerver mind a kliens oldalon aktualizálni kell, hetekig tartó káosz is felléphet.

A háromrétegű alkalmazások, különösen azok, amelyeket Java platformon implementáltak, csökkenteni tudják a szükséges kliensoldali aktualizálást és enyhítik, de nem feltétlenül küszöbölik ki az átállítási kellemetlenségeket, melyek a kliensoldal aktualizálásával járnak. Egy háromrétegű alkalmazásban a kód legnagyobb része a logikai és az adatrétegben van. Mivel e rétegek tipikusan a központi háttérben lévő gépeken üzemelnek, professzionális támogató személyzettel körülvéve, az e rétegekben történő hibajavítások a kliensgépek érintése nélkül elvégezhetők, és anélkül, hogy verzió-eltolódások kerülnének az alkalmazásba. A kliensgépekhez csak akkor kell nyúlni, amikor a rajtuk futó tényleges felhasználói interfész kódot kell aktualizálni. Ebben az esetben a Java platformban található szoftver-igény-szerint lehetőség lehetővé teszi, hogy e változtatásokat elvégezzük az egyes kliensoldali lemezek módosítása nélkül. Akár HTTP-vel Web böngészőn keresztül, akár egy automatikus alkalmazáselosztó rendszeren át osztjuk el az alkalmazsát, a kliensoldali szoftver automatikusan aktualizálható anélkül, hogy megérintenénk az egyes PC-ket.

A jáva szerepe a modell bővítésében

Mivel a Jáva kód platformfüggetlen, a böngészőbe letölthető programkák (applet) a kliens funkcionalitását bővíthetik. Már az első Jáva hálózati könyvtárak is tartalmaztak eljárásokat a HTTP protokollon alapuló kommunikáció egyszerű kezelésére, de ezek a kliens oldalon futó programok az ugyancsak magas szintű könyvtárakkal támogatott TCP-re ill. UDP-re építve saját protokollt is használhatnak a szerver oldali bővítésekkel való  kapcsolattartásra. Némi programozással a Jáva ablakkezelő könyvtára (AWT) csaknem “tetszőleges” bonyolultságú kezelői felületek megvalósítását teszi lehetővé.

A Jáva azonban teljes értékű programozási nyelv, amelyben  programkáknál bonyolultabb alkalmazásokat is írhatunk. A CGI mechanizmus eleve lehetővé teszi, hogy a CGI programokat tetszőleges nyelven, akár Jávában is írhassuk, újabban a szerver fejlesztések trendje, hogy a bővítő programoknál a Jávát, mint teljes értékű nyelvet támogassák: szerver oldali könyvtárak Jávában a Netscape-nél, Jáva kazetta Oracle szerverben, dinamikusan be-, sőt akár letölthető szerverkék (szervlet) a Sun Jeeves szerverében. Az Oracle-nek annyira megtetszett a Jáva, hogy néhány éve az adatbázis-kezelőben tárolt eljárások is íródhatnak Jávában.

A kliens-szerver rendszerek fejlesztésének egyik legnagyobb problémája a beszélgető felek között megfelelő kommunikációs protokoll kialakítása. Igaz, hogy a Web-en manapság mindenki TCP/IP-n beszélget, ez azonban csak szállítási szintű szolgáltatásokat nyújt, erre kell felépítenünk az alkalmazási igényének megfelelő kommunikációt. Az Internet protokollcsaládban a szállítási szint felett már jószerével nem akad újabb réteg, a programozók magukra vannak utalva olyan gyakorta kívánatos feladatok megvalósítására, amelyre az ISO-OSI modell teljes rétegeket definiál, mint például a munkamenet (session) kezelés (OSI viszonyréteg), adatreprezentáció, jelentéstartó információátvitel, titkosítás (OSI megjelenítési réteg). A megoldás is kinálkozik: ha már a  többlépcsős kliens-szerver rendszer minden rétegében Jáva kód fut, készítsünk, “szabványosítsunk” Jáva könyvtárakat a kommunikáció támogatására.

Finta Annamária