Ez a kiadás a következő termékhez készült:
továbbá minden későbbi kiadáshoz és módosításhoz, amennyiben az újabb kiadások ettől eltérően nem jelzik.
A kiadványokat az IBM képviselőjétől vagy az IBM helyi irodájától rendelheti meg.
A dokumentumnak ebben a részében a WebSphere Application Server programozási útmutató az Edge összetevőkhöz célját, szervezését és jelöléseit ismertetjük.
A könyv a WebSphere Application Server, 6.1 Változat Edge összetevők személyre szabására használható alkalmazás programozási felületeket ismerteti. Az információk célközönségét a bedolgozó alkalmazásokat és egyéb egyedi összetevőket készítő programozók adják. A hálózattervezők és a rendszergazdák érdeklődésére szintén számot tarthat a dokumentum, mint a személyre szabási lehetőségek típusainak összefoglalása.
A könyv információinak használatához - az alkalmazni kíván alkalmazás programozási felülettől függően - szükség van a Java vagy a C programozási nyelvben alkalmazott programozási eljárások ismeretére. Az elérhetővé tett felületekben található adatszerkezetek és metódusok dokumentálva vannak, de tisztában kell lennie a saját alkalmazásának elkészítéséhez, saját rendszerén való lefordításához és teszteléséhez szükséges eljárásokkal. Bizonyos felületekhez mintakódokat is biztosítunk, ám a minták kizárólag példaként szolgálnak az Ön saját alkalmazásának összeállításához.
A jelen dokumentáció az alábbi szedési és jelölési konvenciókat alkalmazza.
Jelölés | Jelentés |
---|---|
Félkövér | A grafikus felhasználói felületek elemeire való hivatkozáskor a félkövér szöveg menüt, menüelemet, címkét, gombot, ikont vagy mappát jelöl. Egyes esetekben olyan parancsnév kiemelésére szolgál, amelyet egyébként nehéz volna megkülönböztetni a körülötte található szövegtől. |
Monospace betűtípus | A parancssorba beírandó szöveget ad meg. A képernyőn megjelenő szövegek, a kódminták és a fájlkivonatok szintén Monospace szedésűek. |
Dőlt | Változóértéket jelöl, amelyet Önnek kell megadnia (például a fájlnév értékben meg kell adnia egy fájl nevét). A dőlt betűket kiemelésre és könyvek címének megadására is alkalmazzuk. |
Ctrl-x | Ahol az x egy billentyű neve, a kombináció pedig egy Ctrl+karakter billentyűkombinációt jelöl. A Ctrl-c például azt jelenti, hogy lenyomva kell tartania a Ctrl gombot, miközben a c gombot is lenyomja. |
Return | A Return vagy Enter szóval vagy balra mutató nyíllal jelölt billentyűre hivatkozik. |
% | A Linux és UNIX parancssori héjat jelöli olyan parancsnál, amelynek futtatásához nincs szükség root jogokra. |
# | A Linux és a UNIX parancssori héjat jelöli olyan parancsnál, amelynek futtatásához root jogosultságokra van szükség. |
C:\ | A Windows parancssorát jelöli. |
Parancsok beírása | Ha parancs "beírására" vagy "kiadására" kap utasítást, akkor gépelje be a parancsot, majd nyomja meg a Return gombot. Az "Adja ki az ls parancsot" például azt jelenti, hogy gépelje be az ls karaktersorozatot a parancssorba, majd nyomja meg a Return gombot. |
[ ] | Elhagyható elemeket határol a szintaxisok leírásában. |
{ } | A szintaxisok leírásában listákat határol, amelyek elemei közül ki kell választania egyet. |
| | A szintaxisok leírásában a lehetséges választások { } (kapcsos zárójelek) közé foglalt listájának elemeit választja el egymástól. |
... | A szintaxisok leírásában a három pont azt jelzi, hogy a megelőző elemet egy vagy több alkalommal meg lehet ismételni. A példákban a három pont arra utal, hogy a tömörség megőrzése miatt a példából bizonyos információk kimaradtak. |
A kisegítő lehetőségek a fizikai fogyatékkal élőket, például a mozgásukban vagy látásukban korlátozottakat segítik a szoftvertermékek eredményes használatában. A WebSphere Application Server, 6.1 Változat fontosabb kisegítő lehetőségei a következők:
Szeretnénk a legpontosabb és legjobb minőségű információkkal ellátni Önt, és ehhez fontosak számunkra az Ön visszajelzései. Ha bármilyen megjegyzése van a könyvvel vagy a WebSphere Application Server Edge összetevőkhöz készült dokumentációval kapcsolatban:
Ez a könyv a WebSphere Application Server Edge összetevők személyre szabására használható alkalmazás programozási felületeket tárgyalja. (A WebSphere Application Server Edge összetevők elemei: Caching Proxy és Load Balancer.) A szoftver számos felületet magába foglal, ezekkel a rendszergazdák egyénre szabhatják a telepítéseket, módosíthatják az Edge összetevők közötti párbeszédek módját, illetve lehetővé tehetik az egyéb szoftverrendszerekkel folytatott párbeszédet.
FONTOS: A Caching Proxy az Edge összetevők minden telepítésekor elérhető, kivéve a következőket:
A dokumentumban tárgyalt alkalmazás programozási felületek több kategóriába tartoznak.
A Caching Proxy számos a saját feldolgozási sorozatába illesztett felülettel rendelkezik, amelyek alkalmasak a szabványos feldolgozási műveletek bővítésére vagy egyedi eljárásokra való lecserélésére. A személyre szabás egyaránt jelentheti bizonyos feladatok módosítását vagy hozzáadását, mint például:
Az egyedi alkalmazások, amelyeket Caching Proxy bedolgozóknak is nevezünk, a proxyszerver feldolgozási sorozatának meghatározott pontjain hívódnak meg.
A Caching Proxy alkalmazás programozási felülete bizonyos rendszerszolgáltatások megvalósításában is szerepet kapott. A proxyszerver LDAP-támogatása például beépülővel valósul meg.
Caching Proxy API - A felület és a proxyszerver bedolgozó programok használatára való konfigurálásának részletes ismertetése.
A Load Balancer saját tanácsadók készítésével szabható egyénre. A tanácsadók feladata a tényleges terhelések mérése a szervereken. Egyedi tanácsadóval saját, a rendszer jellemzőinek leginkább megfelelő módszereket valósíthat meg. Ez különösen akkor lehet fontos, ha egyénre szabott vagy saját fejlesztésű webkiszolgáló rendszerrel rendelkezik.
Egyéni tanácsadók- Részletes információk az egyéni tanácsadók készítéséről és használatáról. A szakasz minta-tanácsadókódot is tartalmaz.
Az alkalmazás programozási felületekhez mintakódokat az Edge összetevők CD-ROM-lemezén talál, a samples könyvtárban. A WebSphere Application Server webhelyén további kódmintákat is találhat: www.ibm.com/software/webservers/appserv/
Ebben a részben a Caching Proxy alkalmazás programozási felületét tárgyaljuk: pontosan mit is jelent ez, mire használható és hogyan működik.
FONTOS: A Caching Proxy az Edge összetevők minden telepítésekor elérhető, kivéve a következőket:
Az alkalmazás programozási felület a Caching Proxy interfésze, amely lehetővé teszi a proxyszerver alapszolgáltatásainak kibővítését. Lehetőséget ad bővítmények és bedolgozók írására, valamint egyénre szabott feldolgozás megvalósítására, mint például:
A Caching Proxy alkalmazás programozási felületének használata a következő előnyökkel jár:
Mielőtt hozzáfogna saját Caching Proxy bedolgozó programjainak megírásához, meg kell ismernie a proxyszerver működését. A proxyszerver működése több, egymástól határozottan elkülöníthető feldolgozási lépésre osztható fel. Az API segítségével a lépések mindegyikénél lehetőség van saját, egyéni funkciók megvalósítására. Lehetséges például, hogy el szeretne végezni valamilyen műveletet az ügyfél kérésének beolvasása után és az egyéb feldolgozások elvégzése előtt. Esetleg különleges rutinok futtatására lehet szüksége a hitelesítés során és a kért fájl elküldése után.
Az alkalmazás programozási felülethez előre megadott függvények függvénytára tartozik. A bedolgozó programok az API előre megadott függvényeit meghívva párbeszédet folytathatnak a proxyszerver folyamatával (például módosíthatják a kéréseket, olvashatják és írhatják a fejléceket, illetve írhatnak a proxyszerver naplójába). Ezeket a függvényeket nem szabad összekeverni az Ön által írt bedolgozó függvényekkel, amelyek meghívását a proxyszerver végzi. Az előre meghatározott függvények leírását a következő részben találja meg: Előre meghatározott függvények és makrók.
A proxyszervert a megfelelő lépésnél a szükséges bedolgozó függvények meghívására a szerver konfigurációs fájljában megadott Caching Proxy API utasításokkal veheti rá. Ezeknek az utasításoknak a leírását a következő részben találja: Caching Proxy konfigurációs utasítások az API lépésekhez.
A jelen dokumentum a következő témákat tárgyalja:
Saját Caching Proxy bedolgozó programjainak megírásához ezek az összetevők és eljárások állnak rendelkezésére.
A proxyszerver alapműködése annak alapján bontható lépésekre, hogy az adott fázisban a szerver milyen típusú feldolgozást végez. Minden lépéshez tartozik egy csatlakozási pont, amelyen lehetőség van a saját program futtatására. A Caching Proxy konfigurációs fájljához (ibmproxy.conf) a megfelelő utasításokat hozzáadva megadható, hogy az egyes lépések során mely bedolgozó függvényeket kell meghívni. Egy-egy lépéshez több utasítás is megadható, így a folyamatok egyes lépéseihez több bedolgozó függvény is meghívható.
Egyes lépések a kiszolgálókérési folyamat részét képezik. Más szóval, a proxyszerver ezeket a lépéseket minden olyan alkalommal elvégzi, amikor feldolgoz valamilyen kérést. Más lépések elvégzése független a kérésfeldolgozástól, vagyis a szerver ezeket attól függetlenül hajtja végre, hogy éppen ki kell-e elégítenie valamilyen kérést.
A lefordított saját program egy megosztott objektumba kerül, például DLL vagy .so fájlba, az operációs rendszertől függően. Miközben a szerver végighalad a kérés feldolgozásának lépésein, meghívja az egyes lépésekhez rendelt bedolgozó függvényeket, egészen addig, amíg az egyik függvény azt nem jelzi, hogy lekezelte a kérést. Ha egy lépéshez egynél több bedolgozó függvényt ad meg, a függvények meghívása a hozzájuk tartozó utasítások a konfigurációs fájlban való megadásának sorrendjében történik.
Ha a kérést egyik bedolgozó függvény sem kezelte le (akár mert az adott lépéshez nem adott meg Caching Proxy API utasítást, akár mert a lépéshez tartozó bedolgozó függvény HTTP_NOACTION értéket adott vissza), a szerver végrehajtja a lépéshez tartozó saját alapértelmezett műveletét.
Megjegyzés: Ez minden lépésre igaz, kivéve a Service lépést, amelynek nincs alapértelmezett művelete.
1. ábra - A proxyszerver által végrehajtott lépések, illetve a kérések feldolgozásával kapcsolatos lépések végrehajtási sorrendje.
Az ábrán látható lépések közül négynek a végrehajtása az ügyfelek kéréseinek feldolgozásától függetlenül történik. Ezek a lépések a proxyszerver futtatásával és karbantartásával kapcsolatosak. A következők tartoznak ide:
Az alábbiakban az 1. ábra által megadott lépések szerepét ismertetjük. Megjegyezzük, hogy egy-egy kéréshez nem feltétlenül kerül meghívásra az összes lépés.
A kérés beolvasása után és az egyéb műveletek elvégzése előtt végez feldolgozást.
Ha ez a lépés azt jelzi, hogy a kérés feldolgozása megtörtént (HTTP_OK), akkor a szerver kihagyja a kérésfeldolgozási folyamat további lépéseit, és csak a Transmogrifier, a Log és a PostExit lépéseket hajtja végre.
Elmentett biztonsági tokenek segítségével ellenőrzi a fizikai elérési út védelmét, a hozzáférés-vezérlési listákat és az egyéb hozzáférés-szabályozókat, valamint előállítja az alapszintű hitelesítéshez szükséges WWW-Authenticate fejléceket. Ha a lépés helyettesítésére saját bedolgozó függvényt ír, akkor a fejlécek előállításáról is gondoskodnia kell.
További információk: Hitelesítés és jogosultságkezelés
Visszafejti, ellenőrzi és tárolja a biztonsági tokeneket.
További információk: Hitelesítés és jogosultságkezelés
A feldolgozást a hitelesítés és az objektum megkeresése után, de még a kérés kielégítése előtt végzi.
Ha ez a lépés azt jelzi, hogy a kérés feldolgozása megtörtént (HTTP_OK), akkor a szerver kihagyja a kérésfeldolgozási folyamat további lépéseit, és csak a Transmogrifier, a Log és a PostExit lépéseket hajtja végre.
Az AIX rendszereken szükség van egy export fájlra (például: libsajatprogram.exp), amely tartalmazza a bedolgozó függvények listáját, illetve a programot össze kell szerkeszteni a Caching Proxy API import fájljával, a libhttpdapi.exp fájllal.
Linux, HP-UX és Solaris alatt a libhttpdapi és a libc függvénytárakkal kell összeszerkeszteni.
A Windows alapú rendszereken egy moduldefiníciós fájlra (.def) van szükség, amely felsorolja a bedolgozó függvényeket, illetve a HTTPDAPI.LIB fájllal kell összeszerkeszteni a programot.
Ügyeljen arra, hogy a HTAPI.h fájlt be kell illesztenie, a függvények meghatározásakor pedig a HTTPD_LINKAGE makrót kell használnia. A makró biztosítja, hogy az összes függvény ugyanazokat a hívási jelöléseket használja.
Útmutatásként alkalmazza az alábbi fordítási és összeállítási parancsokat.
cc_r -c -qdbxextra -qcpluscmt program.c
cc_r -bM:SRE -bnoentry -o libprogram.so program.o -bI:libhttpdapi.exp -bE:program.exp
(A parancsot csak az olvashatóság kedvéért osztottuk fel két sorra.)
cc -Ae -c +Z +DAportable
aCC +Z -mt -c +DAportable
gcc -c program.c
ld -G -Bsymbolic -o libprogram.so program.o -lhttpdapi -lc
cc -mt -Bsymbolic -c program.c
cc -mt -Bsymbolic -G -o libprogram.so program.o -lhttpdapi -lc
cl /c /MD /DWIN32 program.c
link httpdapi.lib program.obj /def:program.def /out:program.dll /dll
Az exportok megadásához az alábbi módszerek közül választhat:
Saját, a kérésfeldolgozási lépésekhez tartozó programfüggvényeinek megírásakor kövesse a A bedolgozó függvények prototípusai című részben megadott szintaxist.
A függvények mindegyikének értéket kell adnia a visszatérési kód paraméternek, jelezve, hogy milyen művelet elvégzésére került sor:
A Caching Proxy egyes lépéseihez megadott függvényprototípusok bemutatják a megfelelő formátumot, valamint kapcsolódik hozzájuk az általuk végrehajtható feldolgozás típusának ismertetése. Megjegyezzük, hogy a függvénynevek nincsenek előre meghatározva. A saját függvényeknek egyedi nevet kell adni, az elnevezési megállapodást mindenki maga határozhatja meg. A megértés könnyítése érdekében a jelen dokumentumban a szerver feldolgozási lépéseire utaló neveket használtunk.
Minden bedolgozó függvény esetében bizonyos előre meghatározott API függvények érvényesek. Az előre meghatározott függvények egy része egyes lépéseknél nem érvényes. Az alábbi előre meghatározott API függvényeket az összes bedolgozó függvényből meg lehet hívni:
A további API függvények érvényességét vagy érvénytelenségét az egyes függvények prototípusának leírásánál tüntettük fel.
A függvényeknek átadott handle paraméter értéke az előre meghatározott függvények első argumentumaként adható át. Az előre meghatározott API függvények leírását a következő rész tartalmazza: Előre meghatározott függvények és makrók
void HTTPD_LINKAGE ServerInitFunction ( unsigned char *handle, unsigned long *major_version, unsigned long *minor_version, long *return_code )
A function defined for this step is called once when your module is loaded during server initialization. It is your opportunity to perform initialization before any requests have been accepted.
Although all server initialization functions are called, a error return code from a function in this step causes the server to ignore all other functions configured in the same module as the function that returned the error code. (That is, any other functions contained in the same shared object as the function that returned the error are not called.)
The version parameters contain the proxyszerver's version number; these are supplied by the Caching Proxy.
void HTTPD_LINKAGE PreExitFunction ( unsigned char *handle, long *return_code )
A function defined for this step is called for each request after the request has been read but before any processing has occurred. A plug-in at this step can be used to access the client's request before it is processed by the Caching Proxy.
Valid return codes for the preExit function are the following:
Other return codes must not be used.
If this function returns HTTP_OK, the proxyszerver assumes that the request has been handled. All subsequent request processing steps are bypassed, and only the response steps (Transmogrifier, Log, and PostExit) are performed.
All predefined API functions are valid during this step.
void HTTPD_LINKAGE MidnightFunction ( unsigned char *handle, long *return_code )
A function defined for this step runs daily at midnight and contains no request context. For example, it can be used to invoke a child process to analyze logs. (Note that extensive processing during this step can interfere with logging.)
void HTTPD_LINKAGE AuthenticationFunction ( unsigned char *handle, long *return_code )
A function defined for this step is called for each request based on the request's authentication scheme. This function can be used to customize verification of the security tokens that are sent with a request.
void HTTPD_LINKAGE NameTransFunction ( unsigned char *handle, long *return_code )
Az ehhez a lépéshez megadott függvény minden kéréshez meghívódik. A konfigurációs fájl utasításában lehetőség van egy URL-sablon megadására, amivel elérhető, hogy a bedolgozó függvény csak a sablonnal egyezést mutató kérések esetében hívódjon meg. A névfordítási lépés a kérés feldolgozása előtt játszódik le, és módot ad az URL címek objektumokhoz, például fájlnevekhez való hozzárendelésére.
void HTTPD_LINKAGE AuthorizationFunction ( unsigned char *handle, long *return_code )
Az ehhez a lépéshez megadott függvény minden kéréshez meghívódik. A konfigurációs fájl utasításában lehetőség van egy URL-sablon megadására, amivel elérhető, hogy a bedolgozó függvény csak a sablonnal egyezést mutató kérések esetében hívódjon meg. A jogosultságkezelési lépés a kérés feldolgozása előtt játszódik le, és lehetőséget ad annak ellenőrzésére, hogy a kiválasztott objektum átadható-e az ügyfélnek. Ha alapszintű hitelesítést végez, akkor létre kell hoznia a szükséges WWW-Authenticate fejléceket.
void HTTPD_LINKAGE ObjTypeFunction ( unsigned char *handle, long *return_code )
Az ehhez a lépéshez megadott függvény minden kéréshez meghívódik. A konfigurációs fájl utasításában lehetőség van egy URL-sablon megadására, amivel elérhető, hogy a bedolgozó függvény csak a sablonnal egyezést mutató kérések esetében hívódjon meg. Az objektumtípus lépés a kérés feldolgozása előtt játszódik le, segítségével ellenőrizhető, hogy az objektum létezik-e, illetve elvégezhető az objektum típusának meghatározása.
void HTTPD_LINKAGE PostAuthFunction ( unsigned char *handle, long *return_code )
Az ehhez a lépéshez megadott függvény meghívására a kérés jogosultságkezelése után és a feldolgozás megkezdése előtt kerül sor. Ha a függvény visszatérési értéke HTTP_OK, akkor a proxyszerver úgy veszi, hogy a kérés lekezelése megtörtént. A kérésfeldolgozás további részei kimaradnak, és a rendszer csak a válaszadási lépéseket (Transmogrifier, Log és PostExit) hajtja végre.
Ebben a lépésben a szerver összes előre meghatározott függvénye használható.
void HTTPD_LINKAGE ServiceFunction ( unsigned char *handle, long *return_code )
Az ehhez a lépéshez megadott függvény minden kéréshez meghívódik. A konfigurációs fájl utasításában lehetőség van egy URL-sablon megadására, amivel elérhető, hogy a bedolgozó függvény csak a sablonnal egyezést mutató kérések esetében hívódjon meg. A szolgáltatás lépés feladata a kérés kielégítése, amennyiben ez a PreExit vagy a PostAuthorization lépés során még nem történt meg.
Ebben a lépésben a szerver összes előre meghatározott függvénye használható.
Ha a szolgáltatás függvényt az URL helyett a HTTP metódus alapján szeretné futtatni, akkor tanulmányozza a WebSphere Application Server Caching Proxy adminisztrációs útmutató az Enable utasításról szóló részét.
Ehhez a lépéshez az alábbi négy függvényt kell megvalósítani. (A függvényneveknek nem kell egyezniük az itt szereplőkkel.)
void * HTTPD_LINKAGE openFunction ( unsigned char *handle, long *return_code )
A megnyitás függvény végzi az adatfolyam adatainak feldolgozásához szükséges inicializálási műveleteket (például a pufferfoglalást). Minden a HTTP_OK kódtól eltérő visszatérési kód a szűrő futásának megszakítását okozza (az írás és a bezárás függvény meghívása elmarad). A függvények részéről lehetőség van kitöltetlen mutató visszaadására, így mód nyílik arra, hogy helyet foglaljon egy adatszerkezet számára, majd a további függvények correlator paraméterében visszakapja a mutatót.
void HTTPD_LINKAGE writeFunction ( unsigned char *handle, unsigned char *data, /* a származási szerver által küldött adatok */ unsigned long *length, /* a válaszadatok hossza */ void *correlator, /* a megnyitás függvény által visszaadott mutató */ long *return_code )
Az írás függvény feldolgozza az adatokat, majd képes a szerver előre meghatározott HTTPD_write() függvényének az új vagy megváltozott adatokkal való meghívására. A bedolgozónak nem szabad felszabadítania a számára átadott puffert, illetve ezt a szervertől sem várhatja.
Ha saját írás függvényével nem kívánja módosítani az adatokat, HTTPD_write() függvényt továbbra is meg kell hívnia, akár saját megnyitás, írás vagy bezárás függvényéből, ugyanis ekkora kerül sor az ügyfélnek szánt válasz adatainak átadására. A correlator argumentum az a mutató, amely a saját megnyitás rutinban visszaadott adatpufferre vezet.
void HTTPD_LINKAGE closeFunction ( unsigned char *handle, void *correlator, long *return_code )
A lezárás függvény az adatfolyam feldolgozásának befejezéséhez szükséges takarítási műveleteket végzi el (például a correlator puffer kiürítését és felszabadítását). A correlator argumentum az a mutató, amely a saját megnyitás rutinban visszaadott adatpufferre vezet.
void HTTPD_LINKAGE errorFunction ( unsigned char *handle, void *correlator, long *return_code )
A hiba függvény segítségével hibaoldal küldése előtt takarítás jellegű műveleteket lehet végrehajtani, mint például a pufferelt adatok kiírása és/vagy felszabadítása (illetve mindkettő). Ezen a ponton a rendszer a megnyitás, az írás, és a lezárás függvényt egyaránt meghívja a hibaoldal feldolgozására. A correlator argumentum az a mutató, amely a saját megnyitás rutinban visszaadott adatpufferre vezet.
Megjegyzések:
void HTTPD_LINKAGE GCAdvisorFunction ( unsigned char *handle, long *return_code )
Az ehhez a lépéshez megadott függvény a szemétgyűjtés során a gyorsítótár minden fájljához meghívódik. A függvény révén befolyásolni tudja, hogy mely fájlok maradjanak meg, és melyeket törölje a rendszer. További információkat a GC_* változók kapcsán kaphat.
void HTTPD_LINKAGE ProxyAdvisorFunction ( unsigned char *handle, long *return_code )
Az ehhez a lépéshez megadott függvény meghívására minden proxykérés kiszolgálásakor sor kerül. Segítségével például beállítható a USE_PROXY változó.
void HTTPD_LINKAGE LogFunction ( unsigned char *handle, long *return_code )
Az ehhez a lépéshez megadott függvény meghívására minden kérésnél sor kerül, miután a kérés kielégítése megtörtént, illetve az ügyféllel folytatott kommunikáció befejeződött. A konfigurációs fájl utasításában lehetőség van egy URL-sablon megadására, amivel elérhető, hogy a bedolgozó függvény csak a sablonnal egyezést mutató kérések esetében hívódjon meg. A függvény meghívása független a kérés feldolgozásának sikerességétől vagy sikertelenségétől. Ha nem szeretné, hogy a napló bedolgozó felülbírálja az alapértelmezett naplózási mechanizmust, akkor a visszatérési kódot HTTP_OK helyett HTTP_NOACTION értékre állítsa.
void HTTPD_LINKAGE ErrorFunction ( unsigned char *handle, long *return_code )
Az ehhez a lépéshez megadott függvény minden sikertelen kéréshez meghívásra kerül. A konfigurációs fájl utasításában lehetőség van egy URL-sablon megadására, amivel elérhető, hogy a bedolgozó függvény csak a sablonnal egyezést mutató sikertelen kérések esetében hívódjon meg. A hiba lépés lehetőséget ad a hibaválasz egyénre szabására.
void HTTPD_LINKAGE PostExitFunction ( unsigned char *handle, long *return_code )
Az ehhez a lépéshez megadott függvény minden kéréshez meghívódik, tekintet nélkül annak sikerességére vagy sikertelenségére. A lépés lehetőséget biztosít takarítási jellegű feladatok a bedolgozó által a kérés feldolgozásához lefoglalt erőforrásokra vonatkozó elvégzésére.
void HTTPD_LINKAGE ServerTermFunction ( unsigned char *handle, long *return_code )
Az ehhez a lépéshez megadott függvény meghívására a szerver normál leállításakor kerül sor. Segítségével lehetőség nyílik a a szerver inicializálásának lépése során lefoglalt erőforrások felszabadítására. Ebben a lépésben nem szabad meghívni egyik HTTP_* függvényt sem (az eredményt ellenkező esetben nem lehet megjósolni). Ha a konfigurációs fájlban egynél több Caching Proxy API utasítást ad meg a szerver futásának lezárásához, akkor a rendszer mindegyiket meghívja.
Az alábbi visszatérési kódok megfelelnek a HTTP 1.1-es specifikációknak, amelyeket a World Wide Web Consortium (www.w3.org/pub/WWW/Protocols/) az RFC 2616 dokumentumban tett elérhetővé. A bedolgozó függvényeknek az alábbi értékek egyikével kell visszatérniük.
Érték | Visszatérési kód |
0 | HTTP_NOACTION |
100 | HTTP_CONTINUE |
101 | HTTP_SWITCHING_PROTOCOLS |
200 | HTTP_OK |
201 | HTTP_CREATED |
202 | HTTP_ACCEPTED |
203 | HTTP_NON_AUTHORITATIVE |
204 | HTTP_NO_CONTENT |
205 | HTTP_RESET_CONTENT |
206 | HTTP_PARTIAL_CONTENT |
300 | HTTP_MULTIPLE_CHOICES |
301 | HTTP_MOVED_PERMANENTLY |
302 | HTTP_MOVED_TEMPORARILY |
302 | HTTP_FOUND |
303 | HTTP_SEE_OTHER |
304 | HTTP_NOT_MODIFIED |
305 | HTTP_USE_PROXY |
307 | HTTP_TEMPORARY_REDIRECT |
400 | HTTP_BAD_REQUEST |
401 | HTTP_UNAUTHORIZED |
403 | HTTP_FORBIDDEN |
404 | HTTP_NOT_FOUND |
405 | HTTP_METHOD_NOT_ALLOWED |
406 | HTTP_NOT_ACCEPTABLE |
407 | HTTP_PROXY_UNAUTHORIZED |
408 | HTTP_REQUEST_TIMEOUT |
409 | HTTP_CONFLICT |
410 | HTTP_GONE |
411 | HTTP_LENGTH_REQUIRED |
412 | HTTP_PRECONDITION_FAILED |
413 | HTTP_ENTITY_TOO_LARGE |
414 | HTTP_URI_TOO_LONG |
415 | HTTP_BAD_MEDIA_TYPE |
416 | HTTP_BAD_RANGE |
417 | HTTP_EXPECTATION_FAILED |
500 | HTTP_SERVER_ERROR |
501 | HTTP_NOT_IMPLEMENTED |
502 | HTTP_BAD_GATEWAY |
503 | HTTP_SERVICE_UNAVAILABLE |
504 | HTTP_GATEWAY_TIMEOUT |
505 | HTTP_BAD_VERSION |
Saját bedolgozó függvényeiből szükség esetén meghívhatja a szerver előre meghatározott függvényeit és makróit. Ekkor ezek előre meghatározott nevét és az alább ismertetett formátumot kell alkalmaznia. A paraméterek leírásában az i betű a bemenő paramétert jelzi, az o a kimenő paramétert, az i/o jelzés pedig arra utal, hogy az adott paraméter be- és kivitelre egyaránt használható.
A függvények mindegyike a HTTPD visszatérési kódok valamelyikét adja vissza, függően a kérés sikerességétől. A kódok leírását a következő rész tartalmazza: Az előre meghatározott függvények és makrók visszatérési kódjai.
A függvények meghívásakor első paraméterként a bedolgozónak átadott fájlleírót alkalmazza. Ellenkező esetben a függvény HTTPD_PARAMETER_ERROR hibakódot fog visszaadni. A NULL nem számít érvényes fájlleírónak.
void HTTPD_LINKAGE HTTPD_authenticate ( unsigned char *handle, /* i; fájlleíró */ long *return_code /* o; visszatérési kód */ )
void HTTPD_LINKAGE HTTPD_cacheable_url ( unsigned char *handle, /* i; fájlleíró */ unsigned char *url, /* i; ellenőrizni kívánt URL */ unsigned char *req_method, /* i; kérési módszer az URL címhez */ long *retval /* o; visszatérési kód */ )
A HTTPD_SUCCESS visszatérési érték azt jelzi, hogy az URL tartalma gyorsítótárazható, a HTTPD_FAILURE érték pedig arra utal, hogy a tartalom nem gyorsítótárazható. A függvény visszatérési kódja HTTPD_INTERNAL_ERROR is lehet.
void HTTPD_LINKAGE HTTPD_close ( unsigned char *handle, /* i; fájlleíró */ long *return_code /* o; visszatérési kód */ )
void HTTPD_LINKAGE HTTPD_exec ( unsigned char *handle, /* i; fájlleíró */ unsigned char *name, /* i; a futtatandó parancsfájl neve */ unsigned long *name_length, /* i; a név hossza */ long *return_code /* o; visszatérési kód */ )
void HTTPD_LINKAGE HTTPD_extract ( unsigned char *handle, /* i; fájlleíró */ unsigned char *name, /* i; a kibontani kívánt változó neve */ unsigned long *name_length, /* i; a név hossza */ unsigned char *value, /* o; az a puffer, amelybe el kell helyezni az értéket */ unsigned long *value_length, /* i/o; a puffer mérete */ long *return_code /* o; visszatérési kód */ )
Ha a függvény a HTTPD_BUFFER_TOO_SMALL kódot adja vissza, akkor a kért puffer mérete túl kicsi volt a kibontott érték tárolásához. Ebben az esetben a függvény nem veszi igénybe puffert, de a value_length paramétert frissíti az érték sikeres kibontásához szükséges puffermérettel. Ekkor a kibontást egy legalább a value_length értékben kapott méretű pufferrel kell megismételni.
void HTTPD_LINKAGE HTTPD_file ( unsigned char *handle, /* i; fájlleíró */ unsigned char *name, /* i; az elküldeni kívánt fájl neve */ unsigned long *name_length, /* i; a név hossza */ long *return_code /* o; visszatérési kód */ )
const unsigned char * /* o; a változó értéke */ HTTPD_LINKAGE httpd_getvar( unsigned char *handle, /* i; fájlleíró */ unsigned char *name, /* i; változó neve */ unsigned long *n /* i; a fejlécet tartalmazó tömb indexszáma */ )
A fejlécet tartalmazó tömb indexelése nullával kezdődik. Ha a tömb első elemét szeretné megkapni, az n változónak nullás értéket adjon, míg például a negyedik elemet az n változónak négyes értéket adva kaphatja meg.
void HTTPD_LINKAGE HTTPD_log_access ( unsigned char *handle, /* i; fájlleíró */ unsigned char *value, /* i; a kiírni kívánt adatok */ unsigned long *value_length, /* i; az adatok hossza */ long *return_code /* o; visszatérési kód */ )
Megjegyezzük, hogy százalék (%) szimbólum a szerver hozzáférési naplójába való kiírásakor nincs szükség kilépési (escape) szimbólum használatára.
void HTTPD_LINKAGE HTTPD_log_error ( unsigned char *handle, /* i; fájlleíró */ unsigned char *value, /* i; a kiírni kívánt adatok */ unsigned long *value_length, /* i; az adatok hossza */ long *return_code /* o; visszatérési kód */ )
Megjegyezzük, hogy százalék (%) szimbólum a szerver hibanaplójába való kiírásakor nincs szükség kilépési (escape) szimbólum használatára.
void HTTPD_LINKAGE HTTPD_log_event ( unsigned char *handle, /* i; fájlleíró */ unsigned char *value, /* i; a kiírni kívánt adatok */ unsigned long *value_length, /* i; az adatok hossza */ long *return_code /* o; visszatérési kód */ )
Megjegyezzük, hogy százalék (%) szimbólum a szerver eseménynaplójába való kiírásakor nincs szükség kilépési (escape) szimbólum használatára.
void HTTPD_LINKAGE HTTPD_log_trace ( unsigned char *handle, /* i; fájlleíró */ unsigned char *value, /* i; a kiírni kívánt adatok */ unsigned long *value_length, /* i; az adatok hossza */ long *return_code /* o; visszatérési kód */ )
Megjegyezzük, hogy százalék (%) szimbólum a szerver nyomkövetési naplójába való kiírásakor nincs szükség kilépési (escape) szimbólum használatára.
void HTTPD_LINKAGE HTTPD_open ( unsigned char *handle, /* i; fájlleíró */ long *return_code /* o; visszatérési kód */ )
void HTTPD_LINKAGE HTTPD_proxy ( unsigned char *handle, /* i; fájlleíró */ unsigned char *url_name, /* i; a proxykérés URL címe */ unsigned long *name_length, /* i; az URL hossza */ void *request_body, /* i; a kérés törzse */ unsigned long *body_length, /* i; a törzs hossza */ long *return_code /* o; visszatérési kód */ )
void HTTPD_LINKAGE HTTPD_read ( unsigned char *handle, /* i; fájlleíró */ unsigned char *value, /* i; puffer az adatok számára */ unsigned long *value_length, /* i/o; pufferméret (adathossz) */ long *return_code /* o; visszatérési kód */ )
void HTTPD_LINKAGE HTTPD_restart ( long *return_code /* o; visszatérési kód */ )
Megjegyezzük, hogy a függvénnyel létrehozni is lehet változókat. A létrehozott változókra a HTTP_ és PROXY_ előtagokkal kapcsolatos megállapodások vonatkoznak, amelyek ismertetését a Változók rész tartalmazza. Ha HTTP_ kezdetű változót hoz létre, azt az ügyfél is megkapja a válasz egyik fejléceként, de a HTTP_ előtag nélkül. Ha például Location fejlécet szeretne beállítani, a HTTPD_set() függvényt a HTTP_LOCATION változónévvel kell alkalmaznia. A PROXY_ előtaggal létrehozott változók a tartalomszerverhez intézett kérésekbe kerülnek fejlécként. A CGI_ előtagot kapó változókat a rendszer a CGI programoknak adja át.
A függvény minden lépésben érvényes, ugyanakkor a változókra ez nem igaz.
void HTTPD_LINKAGE HTTPD_set ( unsigned char *handle, /* i; fájlleíró */ unsigned char *name, /* i; a beállítani kívánt érték neve */ unsigned long *name_length, /* i; a név hossza */ unsigned char *value, /* i; az értéket tartalmazó puffer */ unsigned long *value_length, /* i; az érték hossza */ long *return_code /* o; visszatérési kód */ )
long /* o; visszatérési kód */ HTTPD_LINKAGE httpd_setvar ( unsigned char *handle, /* i; fájlleíró */ unsigned char *name, /* i; változó neve */ unsigned char *value, /* i; új érték */ unsigned long *addHdr /* i; fejléc hozzáadása vagy cseréje */ )
Az addHdr paraméter négyféle értéket vehet fel:
Az értékek meghatározása a HTAPI.h fájlban található.
void HTTPD_LINKAGE httpd_variant_insert ( unsigned char *handle, /* i; fájlleíró */ unsigned char *URI, /* i; az objektum URI azonosítója */ unsigned char *dimension, /* i; a variáns mérete */ unsigned char *variant, /* i; a variáns értéke */ unsigned char *filename, /* i; az objektumot tartalmazó fájl */ long *return_code /* o; visszatérési kód */ )
Megjegyzések:
Mozilla 4.0 (compatible; BatBrowser 94.1.2; Bat OS)
void HTTPD_LINKAGE httpd_variant_lookup ( unsigned char *handle, /* i; fájlleíró */ unsigned char *URI, /* az objektum URI azonosítója */ unsigned char *dimension, /* i; a variáns mérete */ unsigned char *variant, /* i; a variáns értéke */ long *return_code); /* o; visszatérési kód */
Ha a függvény első meghívása előtt nem állítja be a tartalom típusát, a szerver feltételezi, hogy CGI adatfolyamot küld.
void HTTPD_LINKAGE HTTPD_write ( unsigned char *handle, /* i; fájlleíró */ unsigned char *value, /* i; az elküldeni kívánt adatok */ unsigned char *value_length, /* i; az adatok hossza */ long *return_code); /* o; visszatérési kód */
A szerver a kérés kiszolgálásának sikerességétől függően az alábbi értékek egyikére állítja be a visszatérési kód paramétert:
Érték | Állapotkód | Magyarázat |
---|---|---|
-1 | HTTPD_UNSUPPORTED | A függvény nem támogatott. |
0 | HTTPD_SUCCESS | A függvény futása sikeres volt, és a kimeneti mezők érvényesek. |
1 | HTTPD_FAILURE | A függvény futása sikertelen volt. |
2 | HTTPD_INTERNAL_ERROR | Belső hiba történt, a kérés feldolgozása nem folytatható. |
3 | HTTPD_PARAMETER_ERROR | Legalább egy átadott paraméter érvénytelen volt. |
4 | HTTPD_STATE_CHECK | Az adott függvény az adott feldolgozási lépésben nem használható. |
5 | HTTPD_READ_ONLY | (Csak a HTTPD_set és a httpd_setvar visszatérési értéke lehet.) A változó írásvédett, a bedolgozó nem állíthatja be az értékét. |
6 | HTTPD_BUFFER_TOO_SMALL | (A HTTPD_set, a httpd_setvar és a HTTPD_read visszatérési értéke lehet.) A rendelkezésre bocsátott puffer túl kicsit volt. |
7 | HTTPD_AUTHENTICATE_FAILED | (Csak a HTTPD_authenticate visszatérési értéke lehet.) A hitelesítés meghiúsult. További információkat a HTTP_RESPONSE és a HTTP_REASON változó vizsgálatával kaphat. |
8 | HTTPD_EOF | (Csak a HTTPD_read visszatérési értéke lehet.) A kérés törzsének végét jelzi. |
9 | HTTPD_ABORT_REQUEST | A kérés teljesítése megszakadt, mert az ügyfél olyan egyedcímkét adott át, amely nem felelt meg a kérés által meghatározott feltételeknek. |
10 | HTTPD_REQUEST_SERVICED | (A HTTPD_proxy visszatérési értéke lehet.) A meghívott függvény befejezte a kérésre történő válaszadást. |
11 | HTTPD_RESPONSE_ALREADY_COMPLETED | A függvény futása sikertelen volt, mert a kérésre történő válaszadás már befejeződött. |
12 | HTTPD_WRITE_ONLY | A változó csak írható, a bedolgozó nem tudja olvasni. |
A kérésfeldolgozás minden lépéséhez tartozik egy konfigurációs utasítás, amellyel meg lehet adni, hogy a bedolgozó függvények melyikét kell meghívni és lefuttatni az adott lépés során. Az utasításokat a szerver konfigurációs fájljához (ibmproxy.conf) annak kézi szerkesztésével és frissítésével is hozzá lehet adni, de erre a célra az API kérésfeldolgozási űrlap is használható a Caching Proxy konfigurációs és adminisztrációs űrlapjai közül.
Ez azt jelenti, hogy a szerver a Service, a NameTrans, az Exec, a Fail, a Map, a Pass, a Proxy, a ProxyWAS és a Redirect utasításokat a konfigurációs fájlon belüli előfordulásuk sorrendjében dolgozza fel. Ha a szerver sikeresen megfeleltetett egy URL címet egy fájlnak, akkor az említett utasítások közül a fennmaradókat már nem olvassa be és dolgozza fel. (A Map utasítás kivételt képet. A proxyszerverek leképezési szabályaikról részletesebb információkat a WebSphere Application Server Caching Proxy adminisztrációs útmutató tartalmaz.)
A konfigurációs fájlbeli utasításoknak az ibmproxy.conf fájlban egyetlen sorban kell szerepelniük, az itt kifejezetten megadottak kivételével szóközök nélkül. Bár a megadott szintaxispéldákban az olvashatóság kedvéért szerepel néhány sortörés, az utasítások tényleges megadásakor ezeken a pontokon nem lehet szóköz.
Az utasításokban használt változók a következő jelentésekkel bírnak:
A Service utasítás esetében egy csillagot (*) kell illesztenie a függvény neve után, amennyiben az elérési út információkhoz is hozzá szeretne férni.
További információkat, ideértve az utasítások szintaxisát is, a WebSphere Application Server Caching Proxy adminisztrációs útmutató tartalmaz.
A Caching Proxy API a 4.6.1-es változatig visszafelé kompatibilis az ICAPI és a GWAPI felülettel.
A C nyelven írt CGI alkalmazások a Caching Proxy API használatára végzett portolásakor kövesse az alábbi irányelveket:
API programok írásakor a Caching Proxy változói révén információkat lehet szerezni a távoli ügyfélről és a szerverrendszerről.
Megjegyzések:
ACCEPT_RANGES BYTES CLIENT_ADDR 9.67.84.3
A változó a PostAuthorization, a PostExit, a ProxyAdvisor és a Log lépés során használható.
http://www.anynet.com/~userk/main.htm
Mon, 01 Mar 2002 19:41:17 GMT
Mon, 01 Mar 1998 19:41:17 GMT
d:\www\adatok
/www/adatok
application/x-www-form-urlencoded
7034
NAME=Eugene+T%2E+Fox&ADDR=etfox%7Cibm.net&INTEREST=xyz
http://www.vallalat.com/honlap
application/x-www-form-urlencoded
A szakkifejezések rövid áttekintése:
3. ábra - A proxyszerver hitelesítési és jogosultságkezelési folyamata.
Amint a 3. ábra látható, a szerver hitelesítési és jogosultságkezelési folyamatának első lépése a hitelesítés kezdeményezése.
A Caching Proxy esetében a hitelesítés a jogosultságkezelési folyamat része, csak akkor kerül rá sor, amikor jogosultságkezelésre van szükség.
A proxyszerver a jogosultság-kezelést igénylő kérések feldolgozásakor a következő lépéseket követi.
Ha a saját készítésű Caching Proxy bedolgozó saját jogosultságkezelési folyamattal rendelkezik, akkor az felülbírálja a szerver alapértelmezett jogosultságkezelési és hitelesítési eljárását. Ha tehát a konfigurációs fájlban van authorization utasítás, akkor a hozzájuk társított bedolgozó függvényeknek szintén kezelniük kell a szükséges hitelesítési eljárásokat. Az előre meghatározott HTTPD_authenticate() függvény a rendelkezésére áll.
A jogosultságkezelő bedolgozókban háromféle módon lehet hitelesítést végezni:
Az Authorization lépés végrehajtásakor lefut a saját készítésű jogosultságkezelő bedolgozó függvény, amely viszont meghívja a hitelesítő bedolgozó függvényt.
Az Authorization lépés végrehajtásakor lefut a saját készítésű bedolgozó függvény, amely viszont meghívja a szerver alapértelmezett hitelesítési eljárását.
Az Authorization lépés elvégzésekor lefut a jogosultságkezelő bedolgozó függvény is, illetve minden benne szereplő hitelesítési eljárás.
Testreszabott hitelesítésre az alábbi megoldással akkor is van lehetőség, ha a saját Caching Proxy bedolgozó nem biztosít külön jogosultságkezelési eljárást:
Az Authorization lépés végrehajtásakor a szerver alapértelmezett jogosultságkezelése is lefut, amely viszont meghívja a saját hitelesítő bedolgozó függvényt.
Vegye figyelembe a következőket:
A variánsok gyorsítótárazásával az eredeti dokumentum (URI) módosított példányát lehet gyorsítótárazni. A Caching Proxy az API által előállított variánsok mindegyikét kezeli. A variánsok egy alapdokumentum különféle változatai.
Általában jellemző, hogy amikor a származási szerverek elküldik a variánsokat, akkor nem jelzi, hogy valójában variánsokról van szó. A Caching Proxy csak a bedolgozók által (például kódlap-átalakítás miatt) előállított variánsokat támogatja. Ha egy bedolgozó a HTTP-fejlécben nem szereplő feltétel alapján hoz létre variánst, akkor egy PreExit vagy PostAuthorization lépésbeli függvénnyel létre kell hoznia egy álfejlécet, amely alapján a Caching Proxy megfelelően azonosítani tudja a meglévő variánst.
Például egy Transmogrifier API programmal a böngésző által küldött User-Agent fejléc értéke alapján módosítani lehet a felhasználók által kért adatokat. A lezárás függvényben mentse el a módosított tartalmat egy fájlba, vagy adjon meg egy pufferhosszt, majd adja át a puffert mint adatargumentumot. Ez után a httpd_variant_insert() és a httpd_variant_lookup() variáns-gyorsítótárazó függvények segítségével helyezze el a tartalmat a gyorsítótárba.
Ha további segítségre van szüksége saját Caching Proxy API függvényeinek elkészítéséhez, akkor tanulmányozza az Edge összetevők telepítő CD-ROM-lemezének samples könyvtárában található mintaprogramokat. További információkat a WebSphere Application Server webhelyen talál: www.ibm.com/software/webservers/appserv/.
Ebben a részben a Load Balancer egyéni tanácsadóit tárgyaljuk.
A tanácsadók szoftveres ügynökök, amelyek a Load Balanceren belül futva információkat nyújtanak egy adott szerver terheléséről. Minden szabványos protokollhoz (HTTP, SSL stb.) külön tanácsadó létezik. A Load Balancer alapkódja rendszeres időközönként végrehajt egy tanácsadói ciklust, amelynek során egyedileg kiértékeli minden a konfigurációjában szereplő szerver állapotát.
Saját Load Balancer tanácsadók készítésével személyre szabhatja a szervergépek terhelésének meghatározására alkalmazott eljárást.
Windows rendszereken: Load Balancer for IPv4 and IPv6 telepítés használatakor, ha IPv6 protokollt alkalmaz a gépen, valamint tanácsadókat kíván futtatni, akkor módosítania kell a C:\windows\system32\drivers\etc\ könyvtárban található protocol fájlt.
IPv6 esetében a következő sort kell beillesztenie a protocol fájlba:
ipv6-icmp 58 IPv6-ICMP # IPv6 interface control message protocol
A tanácsadók általában a következő módon segítik a terheléskiegyenlítést.
A Load Balancerhez mellékelt normál tanácsadók a következő funkciókhoz, szolgáltatásokhoz végeznek tanácsadást. A tanácsadókról részletes információkat a WebSphere Application Server Load Balancer adminisztrációs útmutató tartalmaz.
Az olyan zárt protokollok támogatásához, amelyekhez nincs normál tanácsadó, saját tanácsadót kell készíteni.
Az egyéni tanácsadók kisméretű Java programok, amelyek osztályfájlok formájában állnak rendelkezésre, a Load Balancer alapkódja hívja meg őket az egyes szerverek terhelésének meghatározására. Az alapkód minden szükséges adminisztrációs feladatot elvégez, ideértve az egyéni tanácsadók indítását és leállítását, az állapotadatok és jelentések átadását, az előzmények naplófájlba rögzítését, valamint a tanácsadók állapotának a kezelő összetevő felé végzett jelentését.
Amikor a Load Balancer alapkódja meghív egy egyedi tanácsadót, a következő lépések végrehajtására kerül sor.
Az egyéni tanácsadók a Load Balancerrel normál vagy helyettesítő módú párbeszédet folytathatnak.
A működési mód kiválasztása az egyéni tanácsadó fájljában a konstruktor metódusban, egy paraméter segítségével történik. (Minden tanácsadó az említett módok egyikében működik, tervezésétől függően.)
Normál módban az egyéni tanácsadó adatcserét végez a szerverrel, és a tanácsadó alapkódja végzi az adatcsere időmérését és a terhelési érték kiszámítását. Az alapkód ezt követően jelenti a terhelési értéket a kezelőnek. Az egyéni tanácsadó nulla visszatérési értékkel jelzi a sikert, mínusz egyes értékkel pedig a hibát.
A normál mód kiválasztásához a konstruktor replace jelzőjének false értéket kell adni.
Helyettesítő módban az alapkód nem végez időmérést. Az egyéni tanácsadó kódja elvégzi a megadott műveleteket, az egyéni szükségletek szerint, majd átadja a tényleges terhelési értéket. Az alapkód fogadja a terhelési értéket, majd változatlan formában átadja a kezelőnek. A lehető legjobb eredmény elérése érdekében a terhelési értékeket 10 és 1000 közé kell normalizálni, ahol a 10-es érték gyors, az 1000-es érték pedig lassú szervert jelent.
A helyettesítő mód kiválasztásához a konstruktor replace jelzőjének true értéket kell adni.
Az egyéni tanácsadók fájlneveinek esetében az ADV_név.java formátumot kell követni, ahol a név a tanácsadó számára kiválasztott név. A teljes névnek a nagybetűs ADV_ előtaggal kell kezdődnie, az ezt követő karaktereknek pedig kisbetűknek kell lenniük. A kisbetűk használatára vonatkozó követelmény betartásával biztosítható, hogy a tanácsadó futtatási parancsa érzéketlen legyen a kis- és nagybetűk használatára.
A Java megállapodások szerint a fájlon belül megadott osztály nevének egyeznie kell a fájl nevével.
Az egyéni tanácsadókat Java nyelven kell megírni, és a fejlesztői gépre telepített Java fordítóval kell lefordítani. A fordítás során a következő fájlokra történik hivatkozás:
A fordítás ideje alatt a classpath környezeti változónak az egyéni tanácsadó fájljára és az alaposztályok fájljára egyaránt kell hivatkozást tartalmaznia. A fordítási parancs formátuma például a következő lehet:
javac -classpath /opt/ibm/edge/lb/servers/lib/ibmnd.jar ADV_név.java
A példában a Linux és UNIX alatti alapértelmezett telepítési útvonalat használtuk. A tanácsadó fájljának neve ADV_név.java, és a fájl az aktuális könyvtárban található.
A fordítás kimenete egy class fájl, például ADV_név.class. A tanácsadó elindítása előtt másolja át a class fájlt a telepítési_útvonal/servers/lib/CustomAdvisors/ könyvtárba.
Az egyéni tanácsadó futtatásához először át kell másolni a tanácsadó class fájlját a Load Balancer gép lib/CustomAdvisors/ könyvtárába. Ha például az egyéni tanácsadó neve sajatping, akkor a fájl elérési útja telepítési_útvonal/servers/lib/CustomAdvisors/ADV_sajatping.class lesz.
A Load Balancert úgy kell konfigurálni, hogy indítsa el saját kezelő szolgáltatását, majd adja ki az egyéni tanácsadó elindításához szükséges parancsot. Az egyéni tanácsadó megadása a nevével történik, az ADV_ előtag és a fájlkiterjesztés elhagyásával:
dscontrol advisor start sajatping portszám
A parancsban megadott portszám azt a portot határozza meg, amelyen a tanácsadó kapcsolatot létesít a célszerverrel.
Ahogy minden tanácsadó, az egyéni tanácsadók is az ADV_Base nevű tanácsadói alaposztályt bővitik ki. A tanácsadói funkciók túlnyomó részét a tanácsadói alap végzi, ilyen például a kezelő súlyozó algoritmusa által használt terhelési értékek jelentése a kezelő felé. A tanácsadói alap feladata a socketek csatlakoztatása és lezárása, valamint a tanácsadó által használt küldési és fogadási metódusok biztosítása is. A tanácsadót a rendszer csak a vizsgált szerver felé, a megadott porton való adatküldésre és -fogadásra használja. A tanácsadói alap által biztosított TCP eljárások időméréssel vannak ellátva, ennek alapján történik a terhelés kiszámítása. A tanácsadó alapjának konstruktorában található egyik jelző szükség esetén alkalmas a meglévő terhelés a tanácsadóktól kapott új terheléssel való felülírására.
A tanácsadók a következő alaposztálybeli metódusokkal rendelkeznek:
A kötelező rutinokkal kapcsolatos részleteket a jelen szakasz egy későbbi része tartalmazza.
Az egyéni tanácsadók meghívására a natív, más szóval szabvány tanácsadók keresése után kerül sor. Ha a Load Balancer nem találja valamelyik megadott tanácsadót a szabványos tanácsadók listáján, akkor az egyéni tanácsadók listájához fordul. A tanácsadók használatáról további információkat a WebSphere Application Server Load Balancer adminisztrációs útmutató tartalmaz.
Az egyéni tanácsadók névadása és elérési útjának megválasztása során vegye figyelembe az alábbi követelményeket.
void ADV_Base Constructor ( string sName; string sVersion; int iDefaultPort; int iInterval; string sDefaultLogFileName; boolean replace )
void ADV_AdvisorInitialize()
A metódus segítségével az egyéni tanácsadó esetében szükséges inicializálási műveleteket lehet elvégezni. A metódus meghívására a tanácsadó alapmoduljának elindulása után kerül sor.
Sok esetben, ideértve a szabványos tanácsadókat is, ezt a metódust nem használják semmire, és kódja csupán egy return utasítást tartalmaz. A metódus alkalmas a suppressBaseOpeningSocket metódus meghívására, amelynek használata csak ebből a metódusból érvényes.
int getLoad( int iConnectTime; ADV_Thread *caller )
Az alábbi részekben ismertetett metódusokat és függvényeket az egyéni tanácsadókból lehet meghívni. A metódusokat a tanácsadói alapkód biztosítja.
A függvényhívások egy része közvetlenül is elindítható, például függvénynév() formában, egy részüknél azonban alkalmazni kell a hívó előtagot. A hívó az éppen futtatott egyéni tanácsadót támogató alap tanácsadópéldányt jelenti.
Az ADVLOG függvénnyel az egyéni tanácsadó szöveges üzenetet tud írni a tanácsadói alap naplófájljába. A formátum a következő:
void ADVLOG (int naplószint, string üzenet)
A getAdvisorName függvény egy Java karaktersorozatot ad vissza, amely az egyéni tanácsadó nevének utótag részét tartalmazza. Az ADV_cdload.java nevű tanácsadó esetében például a függvény a cdload értéket adja vissza.
A függvénynek nincs paramétere.
Megjegyezzük, hogy az érték a tanácsadó példányosítása során való megváltoztatására nincs lehetőség.
A getAdviseOnPort függvény annak a portnak a számát adja vissza, amelyen a hívó egyéni tanácsadó fut. A visszatérési érték egy Java integer (int), és a függvénynek nincs paramétere.
Megjegyezzük, hogy az érték a tanácsadó példányosítása során való megváltoztatására nincs lehetőség.
A getCurrentServer függvény a jelenlegi szerver IP címét adja vissza. A visszatérési érték egy Java karaktersorozat, IP cím formátummal, például: 128.0.72.139.
A cím jellemzően az egyéni tanácsadó minden meghívásánál más, ugyanis a tanácsadói alapkód sorra lekérdezi az összes szervergépet.
A függvénynek nincs paramétere.
A getCurrentCluster függvényhívás a jelenlegi szerverfürt IP címét adja vissza. A visszatérési érték egy Java karaktersorozat, IP cím formátummal, például: 128.0.72.139.
A cím jellemzően az egyéni tanácsadó minden meghívásánál más, ugyanis a tanácsadói alapkód sorra lekérdezi az összes szerverfürtöt.
A függvénynek nincs paramétere.
A getInterval függvény a tanácsadási időközt adja vissza, ami a tanácsadói ciklusok közötti másodpercek száma. Az érték egyenlő az egyéni tanácsadó konstruktorában megadott alapértelmezett értékkel, hacsak az értéket a futás során nem módosították a dscontrol paranccsal.
A visszatérési érték egy Java integer (int). A függvénynek nincs paramétere.
A getLatestLoad függvény segítségével az egyéni tanácsadó lekérdezheti egy adott szerverobjektum legutolsó terhelési értékét. A terhelési értékek nyilvántartása a tanácsadói alapkód és a kezelődémon belső táblázataiban történik.
int caller.getLatestLoad (string fürt_IP, int port, string szerver_IP)
A három argumentum együttesen egy kiszolgáló objektumot határoz meg.
A visszatérési érték integer típusú.
A függvényhívás használatának akkor van értelme, ha valamelyik protokoll vagy port viselkedését egy másik viselkedésétől kell függővé tenni. A függvényhívás alkalmas például arra, hogy egy egyéni tanácsadó letiltson egy meghatározott alkalmazáskiszolgálót, ha az azonos gépen futó Telnet szervert letiltották.
A receive függvény információkat fogad a socketkapcsolatról.
caller.receive(stringbuffer *válasz)
A válasz paraméter egy karaktersorozat-puffer, ebbe kerülnek a kapott adatok. A függvény emellett egy integer értéket is átad, amelynek jelentése a következő:
A send függvény a már létrejött socketkapcsolatot veszi igénybe egy csomagnyi adat a megadott porton keresztül a szerverhez való küldésére.
caller.send(string parancs)
A parancs paraméter egy karaktersorozat, amely a szervernek elküldeni kívánt adatokat tartalmazza. A függvény egy integer értéket ad vissza, amelynek jelentése a következő:
A suppressBaseOpeningSocket függvényhívással az egyéni tanácsadó megadhatja, hogy az alap tanácsadó kód nyisson-e TCP socketet a szerver felé az egyéni tanácsadó nevében. Ha a tanácsadó a szerver állapotának meghatározásához nem végez közvetlen kommunikációt a szerverrel, akkor a socket megnyitása valószínűleg szükségtelen.
A függvényhívást csak egyszer, és csak az ADV_AdvisorInitialize rutinból lehet elindítani.
A függvénynek nincs paramétere.
Az alábbi példák az egyéni tanácsadók megvalósítását szemléltetik.
A minta forráskód hasonló a Load Balancer szabványos HTTP-tanácsadójához. Működése a következő:
A tanácsadó normál módban működik, vagyis a terhelésmérés azon alapul, hogy ezredmásodpercben mérve mennyi ideig tart a socket megnyitása, a küldés, a fogadás és a lezárás végrehajtása.
package CustomAdvisors; import com.ibm.internet.lb.advisors.*; public class ADV_sample extends ADV_Base implements ADV_MethodInterface { static final String ADV_NAME ="Sample"; static final int ADV_DEF_ADV_ON_PORT = 80; static final int ADV_DEF_INTERVAL = 7; static final string ADV_SEND_REQUEST = "HEAD / HTTP/1.0\r\nAccept: */*\r\nUser-Agent: " + "IBM_Load_Balancer_HTTP_Advisor\r\n\r\n"; //-------- // Konstruktor public ADV_sample() { super(ADV_NAME, "3.0.0.0-03.31.00", ADV_DEF_ADV_ON_PORT, ADV_DEF_INTERVAL, "", false); super.setAdvisor( this ); } //-------- // ADV_AdvisorInitialize public void ADV_AdvisorInitialize() { return; // általában üres rutin } //-------- // getLoad public int getLoad(int iConnectTime, ADV_Thread caller) { int iRc; int iLoad = ADV_HOST_INACCESSIBLE; // inicializálás elérhetetlenre iRc = caller.send(ADV_SEND_REQUEST); // a HTTP-kérés küldése // a szervernek if (0 <= iRc) { // ha a küldés sikeres StringBuffer sbReceiveData = new StringBuffer(""); // puffer foglalása // a válasz számára iRc = caller.receive(sbReceiveData); // az eredmény fogadása // szükség esetén az eredmény értelmezése if (0 <= iRc) { // ha a fogadás sikeres iLoad = 0; // 0 visszatérési érték jelzi a sikert } // (normál módban az alap figyelmen kívül } // hagyja a tanácsadó terhelési értékét) return iLoad; } }
A minta a tanácsadói alap által megnyitott szabványos socket felülbírálását szemlélteti. A szerver lekérdezéséhez a tanácsadó megnyit helyette egy oldaladatfolyam Java socketet. Az eljárás főként olyan szervereknél alkalmazható, amelyek a normál ügyfélforgalomtól eltérő portot használnak a tanácsadói lekérdezések fogadására.
A példában a szerver a 11999-es porton fogadja a kéréseket, és terhelési értékként a hexadecimális int "4" értéket adja vissza. A mintakód helyettesítő módban fut, vagyis a tanácsadó konstruktorának utolsó paramétere true értékre van állítva, és a tanácsadói alapkód az eltelt idő helyett a kapott terhelési értéket használja.
Megjegyezzük, hogy a supressBaseOpeningSocket() meghívása az inicializálási rutinból történik. Ha nincs szükség adatok küldésére, akkor az alapsocket felülbírálása is szükségtelen. A socket megnyitásával például ellenőrizni lehet, hogy a tanácsadó tud-e csatlakozni a szerverhez. A döntés meghozatala előtt gondosan vizsgálja meg saját alkalmazásának igényeit.
package CustomAdvisors; import java.io.*; import java.net.*; import java.util.*; import java.util.Date; import com.ibm.internet.lb.advisors.*; import com.ibm.internet.lb.common.*; import com.ibm.internet.lb.server.SRV_ConfigServer; public class ADV_sidea extends ADV_Base implements ADV_MethodInterface { static final String ADV_NAME = "sidea"; static final int ADV_DEF_ADV_ON_PORT = 12345; static final int ADV_DEF_INTERVAL = 7; // bájttömb létrehozása a terheléskérési üzenettel static final byte[] abHealth = {(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x04}; public ADV_sidea() { super(ADV_NAME, "3.0.0.0-03.31.00", ADV_DEF_ADV_ON_PORT, ADV_DEF_INTERVAL, "", true); // a helyettesítő mód paramétere true super.setAdvisor( this ); } //-------- // ADV_AdvisorInitialize public void ADV_AdvisorInitialize() { suppressBaseOpeningSocket(); // az alapkód felszólítása arra, hogy // ne nyissa meg a szabványos socketet return; } //-------- // getLoad public int getLoad(int iConnectTime, ADV_Thread caller) { int iRc; int iLoad = ADV_HOST_INACCESSIBLE; // -1 int iControlPort = 11999; // ezen a porton folyik a kommunikáció a szerverrel string sServer = caller.getCurrentServer(); // a lekérdezni kívánt szerver címe try { socket soServer = new Socket(sServer, iControlPort); // socket megnyitása // a szerver felé DataInputStream disServer = new DataInputStream( soServer.getInputStream()); DataOutputStream dosServer = new DataOutputStream( soServer.getOutputStream()); int iRecvTimeout = 10000; // az adatok fogadására vonatkozó időkorlát // beállítása (mértékegysége: ezredmásodperc) soServer.setSoTimeout(iRecvTimeout); dosServer.writeInt(4); // üzenet küldése a szervernek dosServer.flush(); iLoad = disServer.readByte(); // a szerver válaszának fogadása } catch (exception e) { system.out.println("Kivétel történt: " + e); } return iLoad; // a szerver által jelentett terhelés átadása } }
Ez az egyéni tanácsadói minta azt a lehetőséget szemlélteti, hogy adott szerver valamely portjának hibáját fel lehet ismerni egyrészt a saját állapota, másrészt egy ugyanazon a szervergépen, másik porton futó másik szerverdémon állapota alapján. Ha például a 80-as porton futó HTTP-démon elnémul, akkor érdemes lehet a 443-as porton futó SSL-démon felé irányuló forgalom útválasztását is leállítani.
A tanácsadó erőszakosabb a szabványos tanácsadóknál, ugyanis minden olyan szervert, amely nem küld választ, meghibásodottnak vesz, illetve leálltként jelöl meg. A szabványos tanácsadók a nem válaszoló szervereket rendkívül lelassultakként kezelik. Ez a tanácsadó a szervert a HTTP és az SSL porthoz egyaránt leálltként jelöli meg, ha a szerver a kettő közül akár csak az egyik porton nem válaszol.
Az egyéni tanácsadó használatához a rendszergazdának két példányt kell elindítania belőle: egyet a HTTP, és egyet az SSL porthoz. A tanácsadó két globális kivonattáblát példányosít, egyet a HTTP, egyet pedig az SSL számára. Mindegyik tanácsadó megpróbál kommunikálni a saját szerverdémonjával, majd a művelet eredményeit eltárolja a kivonattáblában. Az egyes tanácsadók által az alap tanácsadó osztálynak átadott értékek egyrészt a saját szerverdémonnal folytatott kommunikáció sikerességétől, másrészt a partnertanácsadó a saját démonjával folytatott kommunikációjának sikerességétől függ.
Az alkalmazott egyéni metódusok a következők.
A következő hibaállapotok felismerésére van lehetőség.
A példa a HTTP 80-as és az SSL 443-as portját köti össze, de bármely portkombinációra átírható.
package CustomAdvisors; import java.io.*; import java.net.*; import java.util.*; import java.util.Date; import com.ibm.internet.lb.advisors.*; import com.ibm.internet.lb.common.*; import com.ibm.internet.lb.manager.*; import com.ibm.internet.lb.server.SRV_ConfigServer; //-------- // Az egyéni tanácsadóban használt kivonattáblák táblázatelemének meghatározása class ADV_nte implements Cloneable { private string sCluster; private int iPort; private string sServer; private int iLoad; private Date dTimestamp; //-------- // konstruktor public ADV_nte(string sClusterIn, int iPortIn, string sServerIn, int iLoadIn) { sCluster = sClusterIn; iPort = iPortIn; sServer = sServerIn; iLoad = iLoadIn; dTimestamp = new Date(); } //-------- // az elem érvényességének/lejártának ellenőrzése public boolean isCurrent(ADV_twop oThis) { boolean bCurrent; int iLifetimeMs = 3 * 1000 * oThis.getInterval(); // az élettartam beállítása // 3 tanácsadói ciklusra Date dNow = new Date(); Date dExpires = new Date(dTimestamp.getTime() + iLifetimeMs); if (dNow.after(dExpires)) { bCurrent = false; } else { bCurrent = true; } return bCurrent; } //-------- // értékhozzáférő(k) public int getLoadValue() { return iLoad; } //-------- // klónozás (a szálak közötti sérülések elkerülésére) public synchronized Object Clone() { try { return super.clone(); } catch (cloneNotSupportedException e) { return null; } } } //-------- // az egyéni tanácsadó megadása public class ADV_twop extends ADV_Base implements ADV_MethodInterface, ADV_AdvisorVersionInterface { static final int ADV_TWOP_PORT_HTTP = 80; static final int ADV_TWOP_PORT_SSL = 443; //-------- // a portokhoz tartozó előzményinformációkat tároló táblázatok megadása static HashTable htTwopHTTP = new Hashtable(); static HashTable htTwopSSL = new Hashtable(); static final String ADV_TWOP_NAME = "twop"; static final int ADV_TWOP_DEF_ADV_ON_PORT = 80; static final int ADV_TWOP_DEF_INTERVAL = 7; static final string ADV_HTTP_REQUEST_STRING = "HEAD / HTTP/1.0\r\nAccept: */*\r\nUser-Agent: " + "IBM_LB_Custom_Advisor\r\n\r\n"; //-------- // bájttömb létrehozása az SSL-ügyfelek hello üzenetével public static final byte[] abClientHello = { (byte)0x80, (byte)0x1c, (byte)0x01, // ügyfél hello (byte)0x03, (byte)0x00, // SSL-változat (byte)0x00, (byte)0x03, // rejtjel megadás hossza (byte) (byte)0x00, (byte)0x00, // munkamenet-azonosító hossza (byte) (byte)0x00, (byte)0x10, // kihívási adatok hossza (byte) (byte)0x00, (byte)0x00, (byte)0x03, // rejtjel kiválasztása (byte)0x1A, (byte)0xFC, (byte)0xE5, (byte)Ox20, // kihívási adatok (byte)0xFD, (byte)0x3A, (byte)0x3C, (byte)0x18, (byte)0xAB, (byte)0x67, (byte)0xB0, (byte)0x52, (byte)0xB1, (byte)0x1D, (byte)0x55, (byte)0x44, (byte)0x0D, (byte)0x0A }; //-------- // konstruktor public ADV_twop() { super(ADV_TWOP_NAME, VERSION, ADV_TWOP_DEF_ADV_ON_PORT, ADV_TWOP_DEF_INTERVAL, "", false); // false = a load balancer méri a válaszidőt setAdvisor ( this ); } //-------- // ADV_AdvisorInitialize public void ADV_AdvisorInitialize() { return; } //-------- // szinkronizált PUT és GET hozzáférési rutinok a kivonattáblákhoz synchronized ADV_nte getNte(Hashtable ht, String sName, String sHashKey) { ADV_nte nte = (ADV_nte)(ht.get(sHashKey)); if (null != nte) { nte = (ADV_nte)nte.clone(); } return nte; } synchronized void putNte(Hashtable ht, String sName, String sHashKey, ADV_nte nte) { ht.put(sHashKey,nte); return; } //-------- // getLoadHTTP - a HTTP-terhelés meghatározása a szerver válasza alapján int getLoadHTTP(int iConnectTime, ADV_Thread caller) { int iLoad = ADV_HOST_INACCESSIBLE; int iRc = caller.send(ADV_HTTP_REQUEST_STRING); // kérésüzenet küldése // a szervernek if (0 <= iRc) { // a kérés sikertelenséggel zárult? StringBuffer sbReceiveData = new StringBuffer("") // puffer foglalása // a válasz számára iRc = caller.receive(sbReceiveData); // a szerver válaszának fogadása if (0 <= iRc) { // a fogadás sikertelenséggel zárult? if (0 < sbReceiveData.length()) { // kapunk adatokat? iLoad = SUCCESS; // a kapott adatok figyelmen kívül hagyása // és sikert jelző kód visszaadása } } } return iLoad; } //-------- // getLoadSSL() - az SSL alapú terhelés meghatározása a szerver válasza alapján int getLoadSSL(int iConnectTime, ASV_Thread caller) { int iLoad = ADV_HOST_INACCESSIBLE; int iSocket = caller.getAdvisorSocket(); // hexadecimális kérés küldése a szervernek CMNByteArrayWrapper cbawClientHello = new CMNByteArrayWrapper( abClientHello); int iRc = SRV_ConfigServer.socketapi.sendBytes(iSocket, cbawClientHello); if (0 <= iRc) { // a kérés sikertelenséggel zárult? StringBuffer sbReceiveData = new StringBuffer(""); // puffer foglalása // a válasz számára iRc = caller.receive(sbReceiveData); // a szerver válaszának // fogadása if (0 <= iRc) { // a fogadás sikertelenséggel zárult? if (0 < sbReceiveData.length()) { // kapunk adatokat? iLoad = SUCCESS; // a kapott adatok figyelmen kívül hagyása és a sikert jelző kód visszaadása } } } return iLoad; } //-------- // getLoad - a HTTP és az SSL metódus eredményeinek egyesítése public int getLoad(int iConnectTime, ADV_Thread caller) { int iLoadHTTP; int iLoadSSL; int iLoad; int iRc; String sCluster = caller.getCurrentCluster(); // a jelenlegi fürtcím int iPort = getAdviseOnPort(); String sServer = caller.getCurrentServer(); String sHashKey = sCluster = ":" + sServer; // a kivonattábla kulcsa if (ADV_TWOP_PORT_HTTP == iPort) { // HTTP-szerver kezelése iLoadHTTP = getLoadHTTP(iConnectTime, caller); // a HTTP alapú terhelés lekérdezése ADV_nte nteHTTP = newADV_nte(sCluster, iPort, sServer, iLoadHTTP); putNte(htTwopHTTP, "HTTP", sHashKey, nteHTTP); // a HTTP alapú terheléssel // kapcsolatos információk elmentése ADV_nte nteSSL = getNte(htTwopSSL, "SSL", sHashKey); // az SSL protokollal kapcsolatos // információk lekérdezése if (null != nteSSL) { if (true == nteSSL.isCurrent(this)) { // az időpecsét ellenőrzése if (ADV_HOST_INACCESSIBLE != nteSSL.getLoadValue()) { // működik // az SSL? iLoad = iLoadHTTP; } else { // az SSL nem működik, ezért a HTTP-szervert leálltként kell megjelölni iLoad= ADV_HOST_INACCESSIBLE; } } else { // az SSL protokollal kapcsolatos információk elévültek, // ezért a HTTP-szervert leálltként jelöljük meg iLoad = ADV_HOST_INACCESSIBLE; } } else { // nincs terhelési információ az SSL protokollról, // a getLoadHTTP() eredményeit kell jelenteni iLoad = iLoadHTTP; } } else if (ADV_TWOP_PORT_SSL == iPort) { // SSL-szerver kezelése iLoadSSL = getLoadSSL(iConnectTime, caller); // az SSL alapú terhelés lekérdezése ADV_nte nteSSL = new ADV_nte(sCluster, iPort, sServer, iLoadSSL); putNte(htTwopSSL, "SSL", sHashKey, nteSSL); // az SSL alapú terheléssel kapcsolatos információk mentése ADV_nte nteHTTP = getNte(htTwopHTTP, "SSL", sHashKey); // a HTTP protokollal // kapcsolatos információk lekérdezése if (null != nteHTTP) { if (true == nteHTTP.isCurrent(this)) { // az időpecsét ellenőrzése if (ADV_HOST_INACCESSIBLE != nteHTTP.getLoadValue()) { // a HTTP // működik? iLoad = iLoadSSL; } else { // a HTTP-szerver nem működik, az SSL megjelölése leálltként iLoad = ADV_HOST_INACCESSIBLE; } } else { // a HTTP protokollal kapcsolatos információk elévültek, ezért az SSL protokollt leálltként kell megjelölni iLoad = ADV_HOST_INACCESSIBLE; } } else { // nincs terhelési információ a HTTP protokollról, // a getLoadSSL() eredményeit kell jelenteni iLoad = iLoadSSL; } } //-------- // error handler else { iLoad = ADV_HOST_INACCESSIBLE; } return iLoad; } }
A WebSphere Application Serverhez a telepítési_útvonal/servers/samples/CustomAdvisors/ könyvtárban található egy egyéni tanácsadó példa. A jelen dokumentum nem tartalmazza a teljes kódot.
A teljes tanácsadó csak kismértékben bonyolultabb a példánál. Bővítésként rendelkezik egy különleges értelmező rutinnal, amely tömörebb a fenti példában szereplő StringTokenizer eljárásnál.
A példakód összetettebb része a Java szerver kisalkalmazásban található. Az egyéb metódusok mellett a szerver kisalkalmazás két a szerver kisalkalmazások specifikációja által megkövetelt metódust tartalmaz: az init() és a service() metódust; továbbá a run() metódust, amelynek meglétét a Java.lang.thread class igényli.
A szerver kisalkalmazás kódjának vonatkozó részei az alábbiakban szerepelnek.
... public void init(ServletConfig config) throws ServletException { super.init(config); ... _checker = new Thread(this); _checker.start(); } public void run() { setStatus(GOOD); while (true) { if (!getKeepRunning()) return; setStatus(figureLoad()); setLastUpdate(new java.util.Date()); try { _checker.sleep(_interval * 1000); } catch (Exception ignore) { ; } } } public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { ServletOutputStream out = null; try { out = res.getOutputStream(); } catch (Exception e) { ... } ... res.setContentType("text/x-application-LBAdvisor"); out.println(getStatusString()); out.println(getLastUpdate().toString()); out.flush(); return; } ...
Amikor szabványos hívást intéz az alkalmazáskiszolgáló valamely meglévő részéhez, illetve új kódrészletet ad hozzá, mint saját egyéni tanácsadójának szerveroldali megfelelőjét, akkor szüksége lehet a kapott terhelési értékek vizsgálatára és a szerver viselkedésének módosítására. A Java StringTokenizer osztállyal és a hozzá tartozó metódusokkal könnyen elvégezheti a vizsgálatot.
Egy jellegzetes HTTP-parancs tartalma a következő: GET /index.html HTTP/1.0
A parancsra adott jellemző válasz például a következő lehet.
HTTP/1.1 200 OK Date: Mon, 20 November 2000 14:09:57 GMT Server: Apache/1.3.12 (Linux and UNIX) Content-Location: index.html.en Vary: negotiate TCN: choice Last-Modified: Fri, 20 Oct 2000 15:58:35 GMT ETag: "14f3e5-1a8-39f06bab;39f06a02" Accept-Ranges: bytes Content-Length: 424 Connection: close Content-Type: text/html Content-Language: hu <!DOCTYPE HTML PUBLIC "-//w3c//DTD HTML 3.2 Final//HU"> <HTML><HEAD><TITLE>Tesztoldal</TITLE></HEAD> <BODY><H1>Apache szerver</H1> <HR> <P><P>Ez a webszerver az Apache 1.3.12-es változatát futtatja. <P><HR> <P><IMG SRC="apache_pb.gif" ALT=""> </BODY></HTML>
A jelen esetben érdekes elemek az első sorban találhatók; ezek közül is a legfontosabb a HTTP visszatérési kód.
A HTTP specifikációja osztályokba sorolja a visszatérési kódokat, ezeket a következőképpen foglalhatjuk össze:
Ha pontosan tudja, hogy a szerver várhatóan milyen kódokat ad vissza, akkor nincs szüksége olyan részletes kódra, mint amilyen a példában szerepel. Ne feledje azonban, hogy a felismert visszatérési kódok körének korlátozásával csökkentheti a program későbbi rugalmasságát.
Az alábbi példában egy önálló, Java alapú program szerepel, amely magában foglal egy alapszintű HTTP-ügyfelet. A példában egy egyszerű, általános célú értelmezőt hívunk meg a HTTP-válaszok vizsgálatára.
import java.io.*; import java.util.*; import java.net.*; public class ParseTest { static final int iPort = 80; static final String sServer = "www.ibm.com"; static final String sQuery = "GET /index.html HTTP/1.0\r\n\r\n"; static final String sHTTP10 = "HTTP/1.0"; static final String sHTTP11 = "HTTP/1.1"; public static void main(String[] Arg) { String sHTTPVersion = null; String sHTTPReturnCode = null; String sResponse = null; int iRc = 0; BufferedReader brIn = null; PrintWriter psOut = null; Socket soServer= null; StringBuffer sbText = new StringBuffer(40); try { soServer = new Socket(sServer, iPort); brIn = new BufferedReader(new InputStreamReader( soServer.getInputStream())); psOut = new PrintWriter(soServer.getOutputStream()); psOut.println(sQuery); psOut.flush(); sResponse = brIn.readLine(); try { soServer.close(); } catch (Exception sc) {;} } catch (Exception swr) {;} StringTokenizer st = new StringTokenizer(sResponse, " "); if (true == st.hasMoreTokens()) { sHTTPVersion = st.nextToken(); if (sHTTPVersion.equals(sHTTP110) || sHTTPVersion.equals(sHTTP11)) { System.out.println("HTTP-változat: " + sHTTPVersion); } else { System.out.println("Érvénytelen HTTP-változat: " + sHTTPVersion); } } else { System.out.println("Nincs válasz"); return; } if (true == st.hasMoreTokens()) { sHTTPReturnCode = st.nextToken(); try { iRc = Integer.parseInt(sHTTPReturnCode); } catch (NumberFormatException ne) {;} switch (iRc) { case(200): System.out.println("HTTP válaszkód: OK, " + iRc); break; case(400): case(401): case(402): case(403): case(404): System.out.println("HTTP válaszkód: ügyfélhiba, " + iRc); break; case(500): case(501): case(502): case(503): System.out.println("HTTP válaszkód: szerverhiba, " + iRc); break; default: System.out.println("HTTP válaszkód: ismeretlen, " + iRc); break; } } if (true == st.hasMoreTokens()) { while (true == st.hasMoreTokens()) { sbText.append(st.nextToken()); sbText.append(" "); } System.out.println("HTTP válaszmondat: " + sbText.toString()); } } }