5. Elosztott rendszerek (2012)

A VIK Wikiből

Általános

  • Socket vs keretrendszer (lábbalhajtós vs kézzeltekerős)
  • Szerializálni kell

Távoli eljáráshívás

Függvényhívás

Interfész

  • A fejlesztö definiálja, specifikálja.
  • WebService-ek esetén WSDL adja meg
  • Callback minta esetén a kloens oldalon szerepel
  • CORBA esetén IDL-ben specifikáljuk

Csonk

  • Keretrendszer fordítási időben generálja
  • Callback minta esetén a kliens oldalon szerepel
  • 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;
}

Szerializálás

  • CORBA esteén az OIOP/IIOP specifikálja
  • Callback minta esteén a kliens oldalon szerepel
  • Keretrendszerben gyárilag implementálva van
  • WebService-ek esetén SOAP

Adapter

  • Callback minta esetén a kliens oldalon szerepel
  • CORBA esteén az IDL-ben specifikáljuk
  • 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);
}

Implementáció

  • Fejlesztö implementálja
  • Callback minta esteén a kliens oldalon szerepel

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ő)

Remote Method Invocation

Szerializálás

(l. perzisztencia témakör)

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

Szerver oldal

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);

Kliens oldal

  • 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

  • a LocateRegistry osztály és a Registry interface azonosítja az RMI Registry szolgáltatást
  • megkeresi/létrehozza a Registry-t
  • static Registry createRegistry(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf)
  • static Registry getRegistry(String host, int port, RMIClientSocketFactory csf)

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.

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.

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


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

Naming Service

  • white pages
  • név-elem párokat (név - referencia) kapcsol össze

Trading Service

  • yellow pages
  • szolgáltatás - referencia lista
  • ServiceType - szolgáltatás típusa
    • név, interfész, attribútumok (properties)
  • Offer - ajánlat
    • konkrét referencia
    • konkrét attribútum-értékek
  • ServiceType <-> SQL ábra
    • kötelezö elem a CORBA interfész
  • Offer <-> SQL tábla egy sora
    • körelezö elem a referencia
  • Keresés <-> SQL query
    • megadható, hogy egy szolgáltatástípusban milyen konkrét attribútumértékű ajánlatokat keresünk
    • pl:
       select REFERENCE, ATTRIBUTE* from SERVICE_TYPE where EXPRSSION 
  • Trader Use-casei
    • ajánlatok kezelésé: insert, update, delete, select
    • Trader attribútumok állítása: számosságok, kéréstovábbítás
  • Különbözö helyen futó traderek összekapcsolhatóak linkkel vagy federatrion-nel, mely arra jó hogy az egyikben kezdeményezett keresés a többibe továbbadódhat. Ez a kapcsolat egyirányú. Beállításai:
    • local_only: csak az aktuális traderben keresünk
    • if_no_local: ha az aktuálisban nincs, mehet tovább
    • always: minden elérhetö traderben keresünk

Event Service

  • Alap CORBA kommunikáció = erös csatolás és egy-egy kommunikáció
  • Event Service= nagyobb szétcsatolás, esemény-alapú kommunikáció, több-több kommunikáció.
  • Szerepek: termelő (termeli az eseményeket) és fogyasztó (feldolgozza az eseményeket)
    • Push kommunikációs modell: termelö kezdeményez (meghívja a termelö push metódusás), fogyasztó passzív
    • Pull kommunikációs modell: termelö passzív, fogyasztó kezdeményez (meghívja a termelö pull metódusát)
  • Csatorna: push-pull ment az egy-egy alapú CORBA kommunikációnál is, de a szétcsatoláshoz kell egy csatorna
    • többen csatlakozhatnak rá, nincs közvetlen kapcsolat termelö és fogyasztó között, nincs szükség másik oldali szereplőre, plusz szolgáltatásokat nyújthat
    • a csatlakozáshoz proxy kell, mely interfészt nyújt a termelö felé fogyasztóként és a fogyasztó felé termelőként, illetve tárolja a felgyűlt üzeneteket
    • a kommunikációs modellek keverhetőek
  • Proxy: a supplier proxy-k saját FIFO pufferrel rendelkezdnek
    • push consumer proxy: a push hatására a csatornához továbbítja az eseményt
    • push supplier proxy: a következő eseményt push hívással adja át a fogyasztónak
    • pull supplier proxy: a pull hatására vagy ad egy új eseményt vagy pufferből, vagy blokkol
    • pull comsumer proxy: pull hívással kér új eseményt a termelötöl

Notification Service

  • Plusz szolgáltatások: csatorna factory, események szürése, QoS, NotifyPublish/Subscribe


-- MeszegetoBalazsIstvan - 2008.05.27.

-- Velias - 2009.05.26.

--Szabó Csaba (vita) 2012. december 14., 18:09 (CET)