4. Elosztott rendszerek
A VIK Wikiből
4.1. Általános
- Socket vs keretrendszer (lábbalhajtós vs kézzeltekerős)
- Szerializálni kell
4.2. Távoli eljáráshívás
Függvényhívás
%ATTACHURL%/rmi.png
Csonk
- sorosítva elküldi a paramétereket
- meghívja a távoli függvényt
- visszaveszi a visszatérési értéket
int foo(int x, int y, int z) { Stub stub = getStub("foo"); Stream s = stub.getOutStream(); s.writeInt(x); s.writeInt(y); s.writeInt(z); stub.invoke(); s = stub.getInStream(); int t = s.readInt(); return t; }
Adapter
- beolvassa a paramétereket
- meghívja az implementációt
- visszaküldi a visszatérési értéket
void invoke(Skeleton skeleton) { Stream s = skeleton.getInStream(); int x = s.readInt(); int y = s.readInt(); int z = s.readInt(); int t2 = foo(x,y,z); s = skeleton.getOutStream(); s.writeInt(t2); }
Problémakezelés
- memóriakezelés
- primitív típusok átmennek
- összetett típusoknál deep copy
- elosztott GC
- hálózati hibák
- idempotens műveletnél nincs gond
- at_most_once, at_least_once, exactly_once
- szerver megtalálása
- bedrótozva
- NameService (hierarchikus, név szerinti keresés)
- TradeService (szolgáltatás szerint kereshető)
4.3. Remote Method Invocation
Szerializálás
4.3.1. Biztonság
SecurityManager osztály
- Biztonsági szabályok kezelésére
- SecurityManager System.getSecurityManager()
- System.setSecurityManager(SecurityManager sm)
- SecurityException-t dob hiba esetén
- void check...() típusú függvényekkel lehet ellenőrizni
- file hozzáférés: Read, Write, Delete
- kapcsolat hozzáférés: Connect, Accept, Listen
- általános: Exit, Exec, Permission
- Külső policy fájlból is meg lehet adni a hozzáféréseket
Távoli interfész
- java.rmi.Remote leszármazott
- java.rmi.RemoteException dob
- paraméter: Serializable interfészt megvalósító objektum
4.3.2. Szerver oldal
%ATTACHURL%/rmi-szerver.png
RemoteObject
- távoli objektumok és stub-ok ősosztálya
- boolean equals(Object o) - stubok között is jó
- RemoteRef getRef()
- int hashCode()
- String toString()
- static Remote toStub(Remote obj) - távoli objektum stub-ját adja vissza
RemoteServer
- távoli objektum létrehozása és exportálása
- static String getClientHost()
- static void setLog(OutputStream os)
- static PrintStream getLog()
UnicastRemoteObject
- távoli objektum exportálása, stub elérése
- Object clone()
- static RemoteStub exportObject(Remote r)
- static Remote exportObject(Remote r, int port [RMIClientSocketFactory csf, RMIServerSocketFactory ssf])
- static boolean unexportObject(Remote r, boolean force)
- protected UnicastRemoteObject(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf)
Remote objektum megvalósítás
- delegációval
- az implementáció nem származik le az UnicastRemoteObject-ből
- meghíváskor kell a stub-ot exportálni:
HelloImpl hello_impl = new HelloImpl(); Hello stub = (Hello)UnicastRemoteObject.exportObject(hello_impl, 0); Registry registry = LocateRegistry.getRegistry(); registry.rebind("hello", stub);
- örökléssel
- az implementáció leszármazik az UnicastRemoteObject-ből
- ekkor automatikus az exportálás, konstruktorban megtörténik:
HelloImpl hello_impl = new HelloImpl(); Registry registry = LocateRegistry.getRegistry(); registry.rebind("hello", hello_impl);
4.3.3. Kliens oldal
%ATTACHURL%/rmi-kliens.png
- Stub hivatkozik a távoli objektumra, implementálja annak interfészét
- Stub megkapható: RMI paraméterként, RMI visszatérési értékként vagy NameService segítségével
try { Registry registry = LocateRegistry.getRegistry(); MyInterface intf = (MyInterface)registry.lookup("MyInterface"); intf.myMethod("Arg1"); } catch (Exception e) {e.printStackTrace();}
RMIRegistry
- név-stub párokat tárol
- void bind(String name, Remote obj) - beregisztrál
- String[] list() - kilistáz
- Remote lookup(String name) - kikeres
- void rebind(String name, Remote obj) - beregisztrál/felülír
- void unbind(String name) - kiszed
LocateRegistry
- megkeresi/létrehozza a Registry-t
- static Registry createRegistry(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf)
- static Registry getRegistry(String host, int port, RMIClientSocketFactory csf)
4.3.4. Elosztott GC
- referenciákat számol
- kilens oldalon is van komponense (DGCClient)
- amikor a kiens deszerializál egy távoli objektumra mutató referenciát, akkor a DGCClient egy dirty() hívással jelez
a szerver GC-je felé, hogy az objektumra a kliensenk szüksége van
- erre válaszul a szerver megmondja, hogy mennyi időre tudja garantálni az objektum megtartását a memóriájában
- a DGCClient feladata, hogy meghosszabbítsa ezt az idő a lejárta előtt egy újabb dirty hívással, ha a kliensnek továbbra is szüksége van az objektumra
- ha a SGCClient úgy veszi észre, hogy nincs szüksége a kliensnek tovább a távoli objektumra, akkor ezt a tényt egy clean () hívással jelzi a szerver
GC-je felé
- a szerver eközben számolja, hogy hány távoli referencia van a távoli objektumokra, és ha ez 0-ra csökken, akkor weak referenciával hivatkozik rá
- Egy kliens első dirty hívására inkrementálja a számlálót
- A bérleti idő lejárta után, vagy clean() hívás hatására dekrementálja
- ekkor a GC már eltakaríthatja a távoli objektumot (ha nincs rá lokális ref.)
- sajnos lehet, hogy a kliens hálózati hiba miatt nem tudta megújítani a referenciáját, és ekkor a következő kérése nem fogja megtalálni az objektumot (NULL)
emiatt is szükség van arra, hogy a távoli objektum metódusai RemoteExceptiont dobjanak FORRÁS: http://publib.boulder.ibm.com/infocenter/javasdk/v5r0/index.jsp?topic=/com.ibm.java.doc.diagnostics.50/diag/understanding/rmi_dgc.html
-- MisnyovszkiAndrasSSO - 2009.05.27.
4.3.5 RMI során átadható paraméterek osztályozása és a paraméterátadás módja
- Pass-by-Reference
- a metódus a paraméterre mutató referenciát kap
- a metódus a referencián keresztül éri el a paramétert, amit a hívó tart
- azok adhatóak át így, akik implementálják a Remote interfészt
- Pass-by-Value (Copy)
- a paraméter lemásolódik
- a metódus a másolatot kapja meg, és azon dolgozik
- mindenki más így adódik át
forrás -- Csádám - 2010.05.31.
4.4. Tervezési minták
(l. tervezési minták oldal)
Mobile agent
- Adat és kód egybezárva utazik rendszereken keresztül. Lényegében egy olyan programrész, amelyet az Agency-k futtatni tudnak, és tovább tudják adni.
- A kliens által küldött objektum futtatható kódja nincs meg a szerveren.
- Lehet például arra használni, hogy elküldeni egy adatbázisnak, ott leszelektálja az eredményt, majd azzal visszajön, így ha valamit nem tudunk SQL-be megírni, akkor is csak minimális lesz a hálózati forgalom.
public interface Agent extends Serializable { void run(); }
public interface Agency extends Remote { public Agent accept(Agent a) throws RemoteException; }
Mitöl ügynök az ügynök?
- Aktív és autonóm
- saját szálon fut
- a döntéseit maga hozza
- a környezet figyelembevételével
- Kapcsolatképes (reaktív)
- más ügynökökkel kommunikálhat
- Tanulékony
- a tapasztalatait összegzi
- Mobil
- képes az ügynökségek közötti közlekedésre
Hogyan érkezik az ügynök?
- Hogyan inicializáltjuk?
- void init() metódus
- elég-e a run() metódus ehhez?
- Hogyan regisztrál
- ügynökség automatikusan regisztrálja
- neki kell regszitrálni
- Hogyan állítja be a jogosultságokat?
- mit tehet az ügynök
- mit tehetnek vele mások
4.5. CORBA (OMG szabvány)
- platformfüggetlen megoldás RPC-re
- képes teljesen különböző programnyelvek között is adatátvitelre/függvényhívásra
Interface Description Language (IDL)
- általános interfészleíró nyelv, amiből az egyes programnyelvekre fordítunk
- primitív típusok: char, octet, boolean, short, long, double
- összetett típusok: enum, string, struct, union, sequence, array, valuetype, exception, \x{2026}
- paraméterátadás: in, out, inout
- interfészek IDL-ben, implementáció natív nyelven
IDL -> Java
- xxxHelper: marshallinghoz (szerializáláshoz)
- xxxHolder: inout és out paraméterek kezelésére
- xxxPOA (Portable Object Adapter): Servant-ból származtatva
- kliens: natív típusokkal dolgozhatunk
Szabványos szolgáltatások
- beépített, szabványos megoldások gyakori problémákra
- NamingService, TradingService
- EventService, NotificationService
- Collection, Concurrency, Time, Transaction
-- MeszegetoBalazsIstvan - 2008.05.27.
-- Velias - 2009.05.26.