Download Advanced Ice
Document related concepts
no text concepts found
Transcript
Advanced Ice © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 1 Introducción ● Servicios básicos (ZeroC Ice) ● Técnicas de implementación ● – Application vs. Service vs. IceBoxService – Servant locators Servicios Hesperia – Casos de uso © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 2 J2ME y servicios de localización ● MLP y OpenLS – DirectoryService – Location Service (jerarquía) – Cálculo de rutas – J2ME, Ice, NetBeans – A/V Streaming en J2ME © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 3 Introducción ● ¿De qué partimos? – Desarrollo básico de clientes/servidores con Ice – Familiarización básica con IceGrid © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 4 Estructura lógica de Ice ● Proxies y esqueletos se generan automáticamente a partir de una descripción abstracta de los interfaces Aplicación Cliente Proxy Ice API Núcleo de Ice (cliente) © 2008 Francisco Moya Aplicación Servidora Red Ice API Esqueleto Adaptador de Objeto Núcleo de Ice (servidor) Distributed Systems Architecture - Advanced Ice 5 Secuencia de desarrollo Servidor HelloI.java Server.java Interfaz Hello.ice Compilador slice2java Archivos *.java Client.java Cliente © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 6 Interfaces struct TimeOfDay { short hour; short minute; short second; }; interface Clock { [“ami”] idempotent TimeOfDay getTime(); [“ami”] idempotent void setTime(TimeOfDay time); [“ami”] void modifyAlarm(TimeOfDay alarm, out TimeOfDay prev_alarm); [“ami”, “amd”] bool synchronize(Clock* my_clock); }; © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 7 Proxies directos e indirectos Proxy indirecto IceGrid Registry ¿tipo? Adaptadores bien conocidos Nombre Endpoints Servidor tcp -p 8080 MyObjAd tcp -p 8081:udp -p 8081 Consultar tabla de adaptadores Objetos bien conocidos Nombre Endpoints Hello tcp -p 8080 obj1 tcp -p 8081:udp -p 8081 © 2008 Francisco Moya Servicio Locator id@adptr Distributed Systems Architecture - Advanced Ice id Consultar tabla de objetos Generar proxy directo 8 Application, Service y IceBox.Service © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 9 Application, Service, IceBox ● Hay tres clases de ayuda como base de cada aplicación – Ice::Application ● – Ice::Service ● – Singleton con un único communicator, señales Similar a Application pero se instala como servicio IceBox::Service ● © 2008 Francisco Moya Para compartir entorno de ejecución (servidor de aplicaciones) Distributed Systems Architecture - Advanced Ice 10 Ice::Application public class MyApp extends Ice.Application { public int run(String[] args) { // código del servidor } communicator().waitForShutdown(); return 0; Singleton para inicializar el Communicator public static void main(String[] args) { Ice.Application app = new MyApp(); int status = app.main("MyApp", args); System.exit(status); } }; © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 11 Ice::Application Comportamiento ante interrupciones ● destroyOnInterrupt() – ● shutdownOnInterrupt() – ● Cierra conexiones ordenadamente al interrumpir ignoreInterrupt() – ● Valor por defecto, destruye el communicator Ignora Ctrl-C, Close, SIGHUP, ... callbackOnInterrupt() – Invoca interruptCallback() © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 12 Ice::Application Retener interrupciones ● holdInterrupt() – ● Retiene las causas de interrupción releaseInterrupt() – Restaura la entrega de señales a la aplicación © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 13 Ice::Service #include <Ice/Service.h> class MyService : public Ice::Service { protected: virtual bool start(int, char*[]) { _adapter = communicator()->createObjectAdapter("OA"); _adapter->addWithUUID(new MyServantI); _adapter->activate(); return true; } private: Ice::ObjectAdapterPtr _adapter; }; int main(int argc, char* argv[]) { MyService svc; return svc.main(argc, argv); } Ice::Service solo existe en C++ Está pensada para servicios del sistema © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 14 Ice::Service Extracto del API ● bool start(int, char*[]) – ● bool stop() – ● Libera recursos adquiridos (e.g. conexiones con DB) void disableInterrupt() – ● Crea objetos y adaptadores Ignora Ctrl-C, Close, SIGHUP, ... void enableInterrupt() – Invoca interruptCallback() © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 15 Application vs. Service ● ● API muy similar – Muy fácil migrar de uno a otro – Service llama a waitForShutdown tras el start ¿Cuándo usar Service? – Demonios/servicios sin terminal ● © 2008 Francisco Moya Argumentos --daemon o --service <nombre> Distributed Systems Architecture - Advanced Ice 16 IceBox::Service ● ● ● ¡Nada que ver con Ice::Service! Permite ahorrar recursos compartiendo un único ejecutable – Una sola JVM para los servicios Java – Un solo CLR para los servicios C# – Un solo ejecutable para los servicios C++ – Control externo de la activación de objetos Despliegue y configuración integrada en IceGrid © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 17 IceBox::Service ● Solo es necesario implementar dos operaciones – start se ejecuta después de cargar el servicio – stop se ejecuta cuando IceBox se está cerrando module IceBox { local interface Service { void start(string name, Ice::Communicator communicator, Ice::StringSeq args); void stop(); }; Normalmente desactiva su adaptador }; de objetos e invoca waitForDeactivate antes de liberar recursos © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 18 IceBox::Service Un ejemplo en Java public class MyServiceI implements IceBox.Service { public void start(String name, Ice.Communicator communicator, String[] args) { _adapter = communicator.createObjectAdapter(name); Ice.Object object = new MyServantI(communicator); _adapter.addWithUUID(object); _adapter.activate(); } public void stop() { _adapter.deactivate(); } private Ice.ObjectAdapter _adapter; } © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 19 Ejecutando un servicio IceBox ● Configuramos servicios dentro de cada IceBox IceBox.Service.MyService=MyServiceI --Ice.Config=srv1.cfg Nombre de la clase ● Los parámetros se pasan directamente al servicio El servidor de aplicaciones está en IceBox.Server – Inicializa todo lo que empiece por IceBox.Service. java IceBox.Server --Ice.Config=icebox.cfg Desde IceGrid esto es automático © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 20 Administración remota de IceBox ● Por defecto la gestión remota está desactivada IceBox.ServiceManager.Endpoints=tcp -p 127.0.0.1 -p 10000 IceBox.InstanceName=AppServer1 ● ● Ver IceBox/IceBox.ice – Realimentación de servicios arrancados y parados – Control manual para arrancar y parar servicios Varias herramientas administrativas – IceGridGUI la más habitual – iceboxadmin útil en scripts © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 21 Scaleability and persistence © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 22 FreezeMap ● Associative persistent container – Similar to std::map o java.util.SortedMap – Leverages Ice marshalling routines ● ● We may only store Slice data types – It needs a connection with the database – It is not thread safe! Automatically generated by a compiler © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 23 Freeze Map & Freeze Connection ● A connection may be used to create transactions or to remove an unused index – See Freeze/Connection.ice © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 24 Transactions with Freeze Map ● Transactions are optional with Freeze – By default each update uses a unique txn ● A R/W iterator uses a txn closed by the destructor Freeze::DeadlockException may occur! module Freeze { local interface Transaction { void commit(); void rollback(); }; local interface Connection { Transaction beginTransaction(); idempotent Transaction currentTransaction(); // ... }; }; © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 25 FreezeMap operations ● ● ● ● Users may supply a custom comparator in the constructor Range search: headMap, tailMap, subMap Range search using a secondary index: headMapForIndex, tailMapForIndex, subMapForIndex Indexation (primary key or secondary index) © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 26 FreezeMap generation Map name Key type Value type slice2freezej --dict PhoneMap,string,PhoneBook::Record \ --dict-index PhoneMap,phone \ PhoneBook.ice module PhoneBook { class Record { string phone; string office; }; }; © 2008 Francisco Moya Map of records in a phonebook indexed by name and using the phone as a secondary index Distributed Systems Architecture - Advanced Ice 27 Using a Freeze Map Construct Freeze.Connection conn = Freeze.Util.createConnection(communicator(), "db"); PhoneMap map = new PhoneMap(conn, "phones", true); java.util.Iterator i = map.entrySet().iterator(); Enumerate while (i.hasNext()) { java.util.Map.Entry e = (java.util.Map.Entry)i.next(); PhoneBook.Record r = (PhoneBook.Record) e.getValue(); System.out.println(e.getKey() + "\t" + r.phone); } Insert map.put("Paco", new PhoneBook.Record("3729", "D3.09")); map.remove("Félix"); Erase Index if (map.containsKey("David")) { PhoneBook.Record r = (PhoneBook.Record) map.get("David"); System.out.println(e.getKey() + "\t" + r.phone); } © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 28 Using a Freeze Map (2) Freeze.Map.EntryIterator i = map.findByPhone("3705"); while (i.hasNext()) { java.util.Map.Entry e = (java.util.Map.Entry)i.next(); PhoneBook.Record r = (PhoneBook.Record) e.getValue(); System.out.println(e.getKey() + "\t" + r.phone); } Index using a secondary key © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 29 Comparing keys java.util.Comparator myIndexKeyComparator = ...; String myIndexName = ...; java.util.Map indexComparators = new java.util.HashMap(); indexComparators.put(myIndexName, myIndexKeyComparator); MyIndexedFreezeMap map = new MyIndexedFreezeMap(connection, dbName, true, myMainKeyComparator, For primary indexComparators); key class MyComparator implements java.util.Comparator<MyType> { public int compare(MyType o1, MyType o2) { // o1 > o2 -> 1 // o1 < o2 -> -1 // o1 == o2 -> 0 return ...; } } © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice Comparators for secondary keys 30 Object adapters Active Servant Map Servant Locators © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 31 Active Servant Map ● Each object adapter maintains an Active servant map Request binding ASM is managed using add, remove, ... © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 32 Physical endpoints & published endpoints ● ● An object adapter keeps two sets of Endpoints – Physical: where requests are handled – Published: associated to proxies created by the OA Usually they are the same but they could differ – Port forwarding in gateways – Load balancing in stateless replication Actual listening port MyAdapter.Endpoints=tcp -h Sun1 -p 9999 MyAdapter.PublishedEndpoints=\ tcp -h Sun1 -p 9999:tcp -h Sun2 -p 9999 What is written into the proxies it creates © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 33 Mobility & endpoints ● A mobile element must refresh the published endpoints whenever the address changes local interface ObjectAdapter { void refreshPublishedEndpoints(); // ... }; ● Physical endpoints must be configured with timeouts – Prevents DoS by hostile clients MyAdapter.Endpoints=tcp -h Sun1 -p 9999 -t 10000 © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 34 Routers ● An adapter may be configured to use a Router – Published endpoints are the ones of the Router © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 35 Proxy creation ● When a servant is activated (add, addWithUUID) ● Knowing the identity of the object local interface ObjectAdapter { // ... Object* createProxy(Identity id); Object* createDirectProxy(Identity id); Object* createIndirectProxy(Identity id); }; ● From a text string Si no está activo aún Cuidado con el acoplamiento Mejor solo indirectos local interface Communicator { // ... Object* stringToProxy(string str); }; © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 36 Proxy configuration ● Default options are configured in the adapter MyAdapter.ProxyOptions=-o -f v1 ● By default use oneway and facet v1 Invoking proxy methods oneway twoway datagram batched oneway batched datagram secure © 2008 Francisco Moya -o -t -d -O -D -s ice_oneway() ice_twoway() ice_datagram() ice_batchOneway() ice_batchDatagram() ice_secure() Distributed Systems Architecture - Advanced Ice 37 More than an adapter ● Fine grain control ● Concurrency control (ThreadPools) ● ● Temporary disabling message processing to several related objects at once (hold) Control of message routing using Glacier2 More than one adapter does not improve scaleability nor performance © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 38 Object identity ● ● Two parts May be built from a single text string module Ice { struct Identity { string name; string category; }; }; local interface Communicator { string identityToString(Identity id); Identity stringToIdentity(string id); }; In “MLP/BT:00-12-10-12-11” the string “MLP” would be the category and “BT:0012-10-12-11” would be the name © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 39 Invocation context ● Slice compilers always generate an extra argument module Ice { local dictionary<string, string> Context; enum OperationMode { Normal, \Idempotent }; local struct Current { ObjectAdapter adapter; Connection con; Invoked object Identity id; string facet; string operation; OperationMode mode; User context Context ctx; int requestId; }; }; © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 40 Using the user context java.util.Map<String, String> ctx1 = new java.util.HashMap<String, String>(); ctx1.put("coordinate-system", "default"); Default context MLP.LocationPrx loc = MLP.LocationPrxHelper .checkedCast(obj.ice_context(ctx1)); return loc.locate("BT-00-10-31-12-22-11"); java.util.Map<String, String> ctx1 = new java.util.HashMap<String, String>(); ctx1.put("coordinate-system", "default"); Per invocation context MLP.LocationPrx loc = MLP.LocationPrxHelper .checkedCast(obj); return loc.locate("BT-00-10-31-12-22-11", ctx1); © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 41 ServantLocator ● ● To use the ASM the following must hold – There is enogh RAM for all the objects – Initialization time is acceptable When a method is invoked – If it is not in ASM – Search with a ServantLocator (locate) ObjectAdapter ASM MyObj1 MyObj2 Endpoint ServantLocator MyCateg © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 42 ServantLocator interface ● Locate – Instances and returns a servant → Invocation – Returns null → ObjectNotExistException – User exception → Propagate to client Custom state Propagated to finished module Ice { local interface ServantLocator { Object locate(Current curr, out LocalObject cookie); void finished(Current curr, Object servant, LocalObject cookie); void deactivate(string category); }; }; © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 43 ServantLocator interface (2) ● Finished – Invoked when method invocation returns – Receives the cookie generated by the corresponding locate module Ice { local interface ServantLocator { Object locate(Current curr, out LocalObject cookie); void finished(Current curr, Cookie allows sharing Object servant, information between LocalObject cookie); locate and finished void deactivate(string category); }; }; © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 44 ServantLocator interface (3) ● Deactivate – Invoked when no more locate/finished may be received – E.g. Closing database connections module Ice { local interface ServantLocator { Object locate(Current curr, out LocalObject cookie); void finished(Current curr, Object servant, LocalObject cookie); void deactivate(string category); }; }; © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 45 ServantLocator semantics ● locate/finished per invocation – ● locate, invocation and finished are run in the same thread – ● Association of servant and identity is not automatic locate may be used to begin a transaction and finished to commit deactivate is run after any locate/finished © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 46 Registering a ServantLocator ● We just add it to the object adapter – For a given category – Each interface should use a different category module Ice { local interface ObjectAdapter { // ... void addServantLocator(ServantLocator locator, string category); ServantLocator findServantLocator(string category); }; }; adapter.addServantLocator(new MyCat1Locator(), "MyCat1"); adapter.addServantLocator(new MyCat2Locator(), "MyCat2"); © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 47 ServantLocator skeleton public class MyServantLocator implements Ice.ServantLocator { public Ice.Object locate(Ice.Current c, Ice.LocalObjectHolder cookie) { String name = c.id.name; ServantDetails d; The name is used to extract try { details from the DB (key) d = DB.lookup(name); } catch (DB.error e) { return null; If it is not found, return null } return new PhoneEntryI(d); } public void finished(Ice.Current c, Ice.Object servant, Ice.LocalObject cookie) {} public void deactivate(String category){} } © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 48 Possible uses of ServantLocator ● Incremental initialization – In locate the servant is created and added to ASM ● ● Default servant – ● The ServantLocator implements a Singleton with a single servant Combination of ASM and ServantLocator – – ● Next invocation will not generate a locate ASM only for critical objects (frequently used) ServantLocator for the remaining objects Servant Evictor – Sort of object cache © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 49 Incremental initialization ● ● It reduces the application startup time by delaying object activations until they are used for the first time A ServantLocator registers objects in the ASM – Beware! Several locate may be running at the same time ● ● © 2008 Francisco Moya Serialize locate invocations Check whether the servant was already registered Distributed Systems Architecture - Advanced Ice 50 Incremental initialization Several concurrent locate are possible synchronized public Ice.Object locate(Ice.Current c, Ice.LocalObjectHolder cookie) { Ice.Object servant = c.adapter.find(c.id); if (servant == null) { ServantDetails d; You must check if it is there try { already because several d = DB.lookup(c.id.name); concurrent locates may be } catch (DB.error&) { active return null; } servant = new PhoneEntryI(d); c.adapter.add(servant, c.id); } return servant; Add servant to the ASM } © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 51 Default servant ● A common problem: scalability – Frequently ● ● ● Servants ≈ OO view of a data base Thousands of records → ¿Thousands of servants? Default servant ≈ facade design pattern – For each invocation it incarnates a different object © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 52 Implementing a default servant ● We need as many ServantLocators as interfaces – Each one is a Singleton – Identities encode the table (type) and key ● ● © 2008 Francisco Moya Category encodes the type of the object Name encodes the key field (or a derivative) Distributed Systems Architecture - Advanced Ice 53 Default servant public final class DirectoryLocator implements Ice.ServantLocator { public DirectoryLocator() { _servant = new DirectoryI(); } public Ice.Object locate(Current curr, Ice.LocalObjectHolder cookie) { return _servant; } public void finished(Current curr, Ice.Object servant, java.lang.Object cookie) { } public void deactivate(String category) { } private: Ice.Object _servant; }; © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 54 Default servant (C++) class DirectoryLocator : public virtual Ice::ServantLocator { public: DirectoryLocator() : _servant(new DirectoryI){} virtual Ice::ObjectPtr locate(const Ice::Current&, Ice::LocalObjectPtr&) { return _servant; } virtual void finished(const Ice::Current&, const Ice::ObjectPtr&, const Ice::LocalObjectPtr&){} virtual void deactivate(const std::string&){} private: Ice::ObjectPtr _servant; }; © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 55 Freeze Evictor ● It is a ServantLocator which behaves as an object cache – It requires a persistency engine ● – ● FreezeMap using identity as the key It requires a LRU queue Several versions available – BackgroundSaveEvictor, TransactionalEvictor – Supports lookups using a secondary index © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 56 Freeze Evictor © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 57 Additional infraestructure ● ● An extension of the Slice description Servant Factory – – ● Servant Initializer – – ● Creates new servant instances It is registered in the communicator If servants must be initialized after instantiation Registered in the Evictor Evictor – – It behaves as a Servant Locator of a given OA We may ask the evictor whether an instance was already there (hasObject) © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 58 Specifying state in Slice module IBool { interface R { ["freeze:read", "ami"] idempotent bool get(); }; interface W { ["freeze:write", "ami"] void set(bool v, Ice::Identity oid); }; }; module IBool { class RWPersistent implements R, W { bool myState; }; Usually private }; Implementation details! © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 59 Persistent implementation public class RWI extends IBool.RWPersistent { public void set(boolean v, Ice.Identity oid, Ice.Current current) { myState = v; } The state may be } modified directly public class RWFactory extends Ice.LocalObjectImpl implements Ice.ObjectFactory { public Ice.Object create(String type) { return new RWI(); } Factory pattern for public void destroy() {} each abstract type } © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 60 Instance initialization ● An initializer adds initilization code after the persistent state was recovered from the database – DB connections, computed fields, ... public class RWInitializer extends Ice.LocalObjectImpl implements Freeze.ServantInitializer { public void initialize(Ice.ObjectAdapter oa, Ice.Identity ident, String str, Ice.Object obj) { } } Never invoke the object being initialized © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 61 Evictor interface ● Methods similar to an ObjectAdapter – add, addFacet, remove, removeFacet ● ● Writes in a DB instead of the ASM Identity iterator local interface EvictorIterator { bool hasNext(); Ice::Identity next(); }; EvictorIterator it = evictor.getIterator(“”, 100); facet © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice Batch size 62 Secondary indices ● An Evictor may provide secondary indices generated by slice2freeze/slice2freezej slice2freezej --index MyIndex,IBool::RWPersistent,myState public class MyIndex extends Freeze.Index { //... public Ice.Identity[] findFirst(boolean key, int N); public Ice.Identity[] find(boolean key); public int count(boolean key); }; Associated to the Evictor in the constructor Slows write operations! © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 63 Types of Freeze Evictor ● Several storage strategies – Background save ● ● – ● © 2008 Francisco Moya Unordered, periodic flush, high performance Groups write operations Transactional ● There could be problems after a crash Method invocations are put in a txn Keeps the state consistent after a crash, lower efficiency Potentially it performs more writes Distributed Systems Architecture - Advanced Ice 64 BackgroundSaveEvictor ● A background thread writes to DB periodically – It only writes modified objects – Evictor synchronizes the servant when writing ¡In C++ we must derive from AbstractMutex! Evictor e = Freeze.Util.createBackgroundSaveEvictor( adapter, “db”, Directory for DB Table in DB “MyTable”, new RWInitializer(), indexes, true); Index[] with secondary indices create DB? generated by slice2freezej © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 65 Keeping servants in memory ● To avoid trashing critical objects local interface BackgroundSaveEvictor extends Evictor { void keep(Ice::Identity id); void keepFacet(Ice::Identity id, string facet); void release(Ice::Identity id); void releaseFacet(Ice::Identity id, string facet); }; They are recursive, the keep and the release invocations must be balanced © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 66 TransactionalEvictor ● It uses metadata to know whether it should write – No explicit synchronization – Propagates transactions in co-located servants – Manages deadlocks automatically Evictor e = Freeze.Util.createTransactionalEvictor( adapter, “db”, Directory for DB Table of DB “MyTable”, null, Type for each new RWInitializer(), facet (Map) indexes, Index[] with true); secondary indices create DB? generated by slice2freezej © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 67 Current transaction in the Evictor ● Compatible with FreezeMaps – We may mix FreezeMap and TransactionalEvictor local interface TransactionalEvictor extends Evictor { Transaction getCurrentTransaction(); void setCurrentTransaction(Transaction tx); }; © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 68 Use case communicator().addObjectFactory(new RWFactory(), IBool.RWPersistent.ice_staticId()); Ice.ObjectAdapter oa = communicator().createObjectAdapter("OA"); Freeze.Evictor e = Freeze.Util.createBackgroundSaveEvictor( oa, "db", "hello", new RWInitializer(), null, true); oa.addServantLocator(e, ""); oa.activate(); Ice.Identity ident = Ice.Util.stringToIdentity("obj1"); if (!e.hasObject(ident)) { e.add(new RWI(), ident); } © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 69 IceStorm © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 70 Software distribuido ● El desarrollo de SW distribuido es diferente ● ¿Dónde están los problemas? – Fallos en procesos y en comunicaciones ● – No es posible aislar por completo la lógica de negocio Cuellos de botella en redes de comunicación ● Puede afectar al propio diseño – © 2008 Francisco Moya Imprescindible probar tráfico realista cuanto antes Distributed Systems Architecture - Advanced Ice 71 Cuellos de botella ● Causas muy variadas – Mal diseño de las interfaces remotas ● ● – Mala disposición física de servidores ● – Preferible el envío de datos por lotes Minimizar las invocaciones Aprovechar co-location si es posible Complejidad inherente al sistema ● Aplicar principios generales por subsistemas – – © 2008 Francisco Moya Envíos por lotes (batching) Filtrado de eventos ¡IceStorm! Distributed Systems Architecture - Advanced Ice 72 IceStorm para desacoplar Publicador ● Publica una vez – ● Suscriptores Propaga a tantos como suscriptores Publicar = invocar método sin valores de retorno – Solo semántica push © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 73 IceStorm Características básicas ● ● ● Desacopla producción y consumo Permite usar cualquier protocolo de transporte en cualquier productor o consumidor Proporciona un mecanismo básico de filtrado basado en pesos Link Topic © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 74 IceStorm Características avanzadas ● Soporta mecanismos de gestión de QoS (primitivos) ● Soporta replicación maestro-esclavo ● Consejos – Batch Oneway reduce la sobrecarga Ver la propiedad IceStorm.Flush.Timeout – (Batch) Datagram permite multicast Cuidado con el límite de tamaño de cada datagrama © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 75 IceStorm Características molestas ● ● ● En caso de fallo en la entrega de un mensaje IceStorm desuscribe al suscriptor que falla Entrega fuera de orden salvo que se especifique reliability=ordered e invocaciones twoway Posible pérdida de mensajes si no se usan invocaciones twoway © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 76 IceStorm Interfaz del TopicManager ● El TopicManager actúa como factoría y almacen persistente de Topics module IceStorm { dictionary<string, Topic*> TopicDict; exception TopicExists { string name; }; exception NoSuchTopic { string name; }; interface TopicManager { Topic* create(string name) throws TopicExists; idempotent Topic* retrieve(string name) throws NoSuchTopic; idempotent TopicDict retrieveAll(); idempotent Ice::SliceChecksumDict getSliceChecksums(); }; }; © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 77 IceStorm Interfaz del Topic struct LinkInfo { Topic* theTopic; string name; int cost; }; sequence<LinkInfo> LinkInfoSeq; dictionary<string, string> QoS; interface Topic { idempotent string getName(); idempotent Object* getPublisher(); idempotent Object* getNonReplicatedPublisher(); Object* subscribeAndGetPublisher( QoS theQoS, Object* subscriber) throws AlreadySubscribed, BadQoS; idempotent void unsubscribe(Object* subscriber); idempotent void link(Topic* linkTo, int cost) throws LinkExists; idempotent void unlink(Topic* linkTo) throws NoSuchLink; idempotent LinkInfoSeq getLinkInfoSeq(); void destroy(); }; © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 78 IceStorm Ejemplo de uso: el productor Para proxies indirectos necesita IceGrid Ice.ObjectPrx obj = communicator().stringToProxy("IceStorm/TopicManager"); IceStorm.TopicManagerPrx topicManager = IceStorm.TopicManagerPrxHelper.checkedCast(obj); IceStorm.TopicPrx topic = null; try { topic = topicManager.retrieve("MyTopic"); } catch (IceStorm.NoSuchTopic ex) { topic = topicManager.create("MyTopic"); } Ice.ObjectPrx p = topic.getPublisher().ice_oneway(); MyConsumerPrx consumer = MyConsumerPrxHelper.uncheckedCast(p); while (true) { // obtener datos ¡Peligro! consumer.myReportMethod(data1, data2); } © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 79 IceStorm Ejemplo de uso: el consumidor Para proxies indirectos necesita IceGrid Ice.ObjectPrx obj = communicator().stringToProxy("IceStorm/TopicManager"); IceStorm.TopicManagerPrx topicManager = IceStorm.TopicManagerPrxHelper.checkedCast(obj); Consumer consumer = new ConsumerI(); Ice.ObjectPrx proxy = adapter.addWithUUID(consumer).ice_oneway(); IceStorm.TopicPrx topic = null; try { topic = topicManager.retrieve("MyTopic"); java.util.Map qos = null; topic.subscribeAndGetPublisher(qos, proxy); } El publisher que devuelve catch (IceStorm.NoSuchTopic ex) { dirige mensajes solo a él // Error, no hay topic } // ... topic.unsubscribe(proxy); © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 80 IceStorm Type safety mediante interfaces Slice interface LocationListener { ["nonmutating", "cpp:const"] idempotent void locateReport(Position pos); ["nonmutating", "cpp:const"] idempotent void locateSeqReport(PositionSeq pos); ["nonmutating", "cpp:const"] idempotent void locateRangeReport(PositionSeq pos); }; interface LocationAdmin extends LocationDataProvider { void addListener(LocationListener* listener); void removeListener(LocationListener* listener); }; Soluciones similares en IceGrid, IceBox, ... © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 81 Coste de mensajes y enlaces ● ● Mensajes solo se propagan un nivel El peso del enlace limita la propagación a los mensajes de peso igual o superior java.util.HashMap ctx = new java.util.HashMap(); ctx.put("cost", "5"); consumer.myReport(data, ctx); © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 82 Calidad de servicio ● Muy pocos parámetros – reliability=ordered – retryCount=N (-1 reintentos infinitos) java.util.Map qos = new java.util.HashMap(); qos.put("reliability", "ordered"); topic.subscribeAndGetPublisher(qos, proxy.ice_twoway()); © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 83 IceStorm replicado ● ● La réplica con máxima prioridad es el coordinador – Algoritmo de García Molina – Transparent fail-over Publishers tienen múltiples endpoints – Se puede restringir a la réplica activa con getNonReplicatedPublisher © 2008 Francisco Moya Distributed Systems Architecture - Advanced Ice 84
Related documents