Download Advanced Ice
Document related concepts
no text concepts found
Transcript
Advanced Ice
© 2008 Francisco Moya
Introducción
●
Servicios básicos (ZeroC Ice)
●
Técnicas de implementación
●
1
Distributed Systems Architecture - Advanced Ice
J2ME y servicios de localización
●
MLP y OpenLS
–
DirectoryService
–
Application vs. Service vs. IceBoxService
–
Location Service (jerarquía)
–
Servant locators
–
Cálculo de rutas
Servicios Hesperia
–
J2ME, Ice, NetBeans
Casos de uso
–
A/V Streaming en J2ME
–
© 2008 Francisco Moya
2
Distributed Systems Architecture - Advanced Ice
© 2008 Francisco Moya
Introducción
●
Estructura lógica de Ice
¿De qué partimos?
–
Desarrollo básico de clientes/servidores con Ice
–
Familiarización básica con IceGrid
●
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
Distributed Systems Architecture - Advanced Ice
3
Distributed Systems Architecture - Advanced Ice
4
© 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
Interfaces
Servidor
struct TimeOfDay {
short hour;
short minute;
short second;
};
HelloI.java
Server.java
Compilador
slice2java
Interfaz
Hello.ice
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);
};
Archivos
*.java
Client.java
Cliente
© 2008 Francisco Moya
6
Distributed Systems Architecture - Advanced Ice
© 2008 Francisco Moya
7
Distributed Systems Architecture - Advanced Ice
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
id@adptr
Servicio
Locator
id
Application, Service y IceBox.Service
Consultar tabla
de objetos
Endpoints
Hello
tcp -p 8080
obj1
tcp -p 8081:udp -p 8081
© 2008 Francisco Moya
Generar
proxy directo
8
Distributed Systems Architecture - Advanced Ice
© 2008 Francisco Moya
Application, Service, IceBox
●
Ice::Service
–
IceBox::Service
●
© 2008 Francisco Moya
// código del servidor
Singleton con un único communicator, señales
–
●
}
Similar a Application pero se instala como servicio
Para compartir entorno de ejecución (servidor de
aplicaciones)
Distributed Systems Architecture - Advanced Ice
};
10
11
Ice::Application
Retener interrupciones
●
Valor por defecto, destruye el communicator
●
callbackOnInterrupt()
holdInterrupt()
–
●
Cierra conexiones ordenadamente al interrumpir
ignoreInterrupt()
–
Distributed Systems Architecture - Advanced Ice
Ice::Application
●
–
© 2008 Francisco Moya
Comportamiento ante interrupciones
shutdownOnInterrupt()
–
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);
}
destroyOnInterrupt()
–
●
public class MyApp extends Ice.Application {
public int run(String[] args) {
Ice::Application
●
●
Ice::Application
Hay tres clases de ayuda como base de cada
aplicación
–
9
Distributed Systems Architecture - Advanced Ice
Retiene las causas de interrupción
releaseInterrupt()
–
Restaura la entrega de señales a la aplicación
Ignora Ctrl-C, Close, SIGHUP, ...
Invoca interruptCallback()
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
12
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
13
Ice::Service
Ice::Service
Extracto del API
#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;
};
●
bool start(int, char*[])
–
bool stop()
●
void disableInterrupt()
●
void enableInterrupt()
–
–
int main(int argc, char* argv[]) {
MyService svc;
return svc.main(argc, argv);
}
Crea objetos y adaptadores
●
–
Libera recursos adquiridos (e.g. conexiones con DB)
Ignora Ctrl-C, Close, SIGHUP, ...
Invoca interruptCallback()
Ice::Service solo existe en C++
Está pensada para servicios del sistema
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
14
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
Application vs. Service
●
●
API muy similar
IceBox::Service
¡Nada que ver con Ice::Service!
●
–
Muy fácil migrar de uno a otro
–
Service llama a waitForShutdown tras el start
Permite ahorrar recursos compartiendo un único
ejecutable
●
¿Cuándo usar Service?
–
Demonios/servicios sin terminal
●
Argumentos --daemon o --service <nombre>
Distributed Systems Architecture - Advanced Ice
16
–
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
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
Un ejemplo en Java
Solo es necesario implementar dos operaciones
–
start se ejecuta después de cargar el servicio
–
stop se ejecuta cuando IceBox se está cerrando
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();
}
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
public void stop() {
_adapter.deactivate();
}
private Ice.ObjectAdapter _adapter;
}
18
© 2008 Francisco Moya
Ejecutando un servicio IceBox
●
Configuramos servicios dentro de cada IceBox
●
Inicializa todo lo que empiece por IceBox.Service.
●
java IceBox.Server --Ice.Config=icebox.cfg
Desde IceGrid esto
es automático
© 2008 Francisco Moya
Por defecto la gestión remota está desactivada
Los parámetros se pasan
directamente al servicio
El servidor de aplicaciones está en IceBox.Server
–
19
IceBox.ServiceManager.Endpoints=tcp -p 127.0.0.1 -p 10000
IceBox.InstanceName=AppServer1
●
●
Distributed Systems Architecture - Advanced Ice
Administración remota de IceBox
IceBox.Service.MyService=MyServiceI --Ice.Config=srv1.cfg
Nombre de la clase
17
IceBox::Service
IceBox::Service
●
15
Distributed Systems Architecture - Advanced Ice
20
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
FreezeMap
●
Associative persistent container
–
Similar to std::map o java.util.SortedMap
–
Leverages Ice marshalling routines
–
It needs a connection with the database
–
It is not thread safe!
●
Scaleability and persistence
●
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
22
Automatically generated by a compiler
© 2008 Francisco Moya
Freeze Map & Freeze Connection
●
A connection may be used to create transactions or
to remove an unused index
–
23
Distributed Systems Architecture - Advanced Ice
Transactions with Freeze Map
●
Transactions are optional with Freeze
–
See Freeze/Connection.ice
We may only store Slice data types
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
24
© 2008 Francisco Moya
FreezeMap operations
●
●
●
●
FreezeMap generation
Users may supply a custom comparator in the
constructor
Map name
Range search:
headMap, tailMap, subMap
module PhoneBook {
class Record {
string phone;
string office;
};
};
Indexation (primary key or secondary index)
Distributed Systems Architecture - Advanced Ice
26
© 2008 Francisco Moya
Using a Freeze Map
Construct
Freeze.Connection conn =
Freeze.Util.createConnection(communicator(), "db");
PhoneMap map = new PhoneMap(conn, "phones", true);
Value type
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 (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
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");
Key type
slice2freezej --dict PhoneMap,string,PhoneBook::Record \
--dict-index PhoneMap,phone \
PhoneBook.ice
Range search using a secondary index:
headMapForIndex, tailMapForIndex,
subMapForIndex
© 2008 Francisco Moya
25
Distributed Systems Architecture - Advanced Ice
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
© 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
Object adapters
Active Servant Map
Servant Locators
Comparators for
secondary keys
30
Distributed Systems Architecture - Advanced Ice
© 2008 Francisco Moya
Physical endpoints
& published endpoints
Active Servant Map
●
Each object adapter maintains an
Active servant map
●
●
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
Request binding
What is written into the proxies it creates
ASM is managed using
add, remove, ...
© 2008 Francisco Moya
32
Distributed Systems Architecture - Advanced Ice
© 2008 Francisco Moya
A mobile element must refresh the published
endpoints whenever the address changes
33
Distributed Systems Architecture - Advanced Ice
Mobility & endpoints
●
31
Distributed Systems Architecture - Advanced Ice
Routers
●
An adapter may be configured to use a Router
–
Published endpoints are the ones of the Router
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
34
Distributed Systems Architecture - Advanced Ice
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
Proxy creation
●
When a servant is activated (add, addWithUUID)
●
Knowing the identity of the object
●
From a text string
Distributed Systems Architecture - Advanced Ice
Default options are configured in the adapter
MyAdapter.ProxyOptions=-o -f v1
●
Cuidado con el acoplamiento
Mejor solo indirectos
local interface Communicator {
// ...
Object* stringToProxy(string str);
};
© 2008 Francisco Moya
Proxy configuration
●
Si no está
activo aún
local interface ObjectAdapter {
// ...
Object* createProxy(Identity id);
Object* createDirectProxy(Identity id);
Object* createIndirectProxy(Identity id);
};
36
35
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
Object identity
●
Fine grain control
●
●
Concurrency control (ThreadPools)
●
●
●
Temporary disabling message processing to several
related objects at once (hold)
Two parts
May be built from a
single text string
module Ice {
struct Identity {
string name;
string category;
};
};
Control of message routing using Glacier2
local interface Communicator {
string identityToString(Identity id);
Identity stringToIdentity(string id);
};
More than one adapter does
not improve scaleability nor
performance
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
38
© 2008 Francisco Moya
Invocation context
●
Slice compilers always generate an extra argument
java.util.Map<String, String> ctx1 =
new java.util.HashMap<String, String>();
ctx1.put("coordinate-system", "default");
facet;
operation;
mode;
User context
ctx;
requestId;
40
© 2008 Francisco Moya
ServantLocator
●
●
To use the ASM the following must hold
41
Distributed Systems Architecture - Advanced Ice
ServantLocator interface
●
Locate
–
There is enogh RAM for all the objects
–
Instances and returns a servant → Invocation
–
Initialization time is acceptable
–
Returns null → ObjectNotExistException
–
User exception → Propagate to client
When a method is
invoked
–
If it is not in ASM
–
Search with a
ServantLocator
(locate)
ObjectAdapter
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);
};
};
ASM
MyObj1
MyObj2
Endpoint
ServantLocator
MyCateg
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
42
© 2008 Francisco Moya
ServantLocator interface (2)
●
Per invocation
context
MLP.LocationPrx loc = MLP.LocationPrxHelper
.checkedCast(obj);
return loc.locate("BT-00-10-31-12-22-11", ctx1);
};
Distributed Systems Architecture - Advanced Ice
Default
context
MLP.LocationPrx loc = MLP.LocationPrxHelper
.checkedCast(obj.ice_context(ctx1));
return loc.locate("BT-00-10-31-12-22-11");
};
© 2008 Francisco Moya
Using the user context
java.util.Map<String, String> ctx1 =
new java.util.HashMap<String, String>();
ctx1.put("coordinate-system", "default");
module Ice {
local dictionary<string, string> Context;
enum OperationMode { Normal, \Idempotent };
local struct Current {
ObjectAdapter
adapter;
Connection
con;
Invoked object
Identity
id;
string
string
OperationMode
Context
int
39
Distributed Systems Architecture - Advanced Ice
Finished
Distributed Systems Architecture - Advanced Ice
ServantLocator interface (3)
●
Deactivate
–
Invoked when method invocation returns
–
–
Receives the cookie generated by the corresponding
locate
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);
};
};
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
43
44
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
45
ServantLocator semantics
●
locate/finished per invocation
–
●
●
●
Association of servant and identity is not automatic
locate, invocation and finished are run in the same
thread
–
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);
};
};
locate may be used to begin a transaction and
finished to commit
deactivate is run after any locate/finished
adapter.addServantLocator(new MyCat1Locator(), "MyCat1");
adapter.addServantLocator(new MyCat2Locator(), "MyCat2");
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
46
© 2008 Francisco Moya
ServantLocator skeleton
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
Incremental initialization
–
In locate the servant is created and added to ASM
●
●
●
The ServantLocator implements a Singleton with a
single servant
Combination of ASM and ServantLocator
–
–
●
ASM only for critical objects (frequently used)
ServantLocator for the remaining objects
Servant Evictor
–
Sort of object cache
© 2008 Francisco Moya
Incremental initialization
●
●
It reduces the application startup time by delaying
object activations until they are used for the first
time
●
Serialize locate invocations
Check whether the servant was already registered
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
Incremental initialization
50
© 2008 Francisco Moya
Default servant
●
A common problem: scalability
–
●
●
Servants ≈ OO view of a data base
Thousands of records → ¿Thousands of servants?
–
51
We need as many ServantLocators as interfaces
–
Each one is a Singleton
–
Identities encode the table (type) and key
●
Default servant ≈ facade design pattern
Distributed Systems Architecture - Advanced Ice
Implementing a default servant
●
Frequently
●
49
Several concurrent locate are possible
Beware! Several locate may be running at the same
time
●
Distributed Systems Architecture - Advanced Ice
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
}
A ServantLocator registers objects in the ASM
–
Next invocation will not generate a locate
Default servant
–
48
47
Possible uses of ServantLocator
●
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){}
}
Distributed Systems Architecture - Advanced Ice
●
Category encodes the type of the object
Name encodes the key field (or a derivative)
For each invocation it incarnates a different object
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
52
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
53
Default servant
public final
class DirectoryLocator implements Ice.ServantLocator
{
public DirectoryLocator() { _servant = new DirectoryI(); }
Default servant (C++)
class DirectoryLocator : public virtual Ice::ServantLocator {
public:
DirectoryLocator() : _servant(new DirectoryI){}
public Ice.Object locate(Current curr,
Ice.LocalObjectHolder cookie) {
return _servant;
}
virtual Ice::ObjectPtr locate(const Ice::Current&,
Ice::LocalObjectPtr&) {
return _servant;
}
public void finished(Current curr, Ice.Object servant,
java.lang.Object cookie) {
}
virtual void finished(const Ice::Current&,
const Ice::ObjectPtr&,
const Ice::LocalObjectPtr&){}
public void deactivate(String category) {
}
virtual void deactivate(const std::string&){}
private:
Ice::ObjectPtr _servant;
};
private:
Ice.Object _servant;
};
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
54
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
Freeze Evictor
●
Freeze Evictor
It is a ServantLocator which behaves as an object
cache
–
It requires a persistency engine
–
It requires a LRU queue
●
●
FreezeMap using identity as the key
Several versions available
–
BackgroundSaveEvictor, TransactionalEvictor
–
Supports lookups using a secondary index
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
56
© 2008 Francisco Moya
Additional infraestructure
●
●
–
–
●
Creates new servant instances
It is registered in the communicator
If servants must be initialized after instantiation
Registered in the Evictor
Evictor
–
–
module IBool {
class RWPersistent implements R, W {
bool myState;
};
Usually private
};
Implementation details!
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
57
module IBool {
interface R {
["freeze:read", "ami"]
idempotent bool get();
};
interface W {
["freeze:write", "ami"]
void set(bool v, Ice::Identity oid);
};
};
Servant Initializer
–
Distributed Systems Architecture - Advanced Ice
Specifying state in Slice
An extension of the Slice description
Servant Factory
–
●
55
58
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
Persistent implementation
Instance initialization
●
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
59
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)
{
}
}
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
}
Never invoke the object
being initialized
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
60
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
61
Evictor interface
●
Methods similar to an ObjectAdapter
–
●
add, addFacet, remove, removeFacet
●
●
Secondary indices
An Evictor may provide secondary indices
generated by slice2freeze/slice2freezej
Writes in a DB instead of the ASM
Identity iterator
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);
};
local interface EvictorIterator {
bool hasNext();
Ice::Identity next();
};
Associated to the Evictor in the constructor
Slows write operations!
EvictorIterator it = evictor.getIterator(“”, 100);
facet
© 2008 Francisco Moya
Batch
size
Distributed Systems Architecture - Advanced Ice
62
© 2008 Francisco Moya
Types of Freeze Evictor
●
Several storage strategies
–
Background save
●
●
–
●
●
© 2008 Francisco Moya
BackgroundSaveEvictor
●
There could be problems
after a crash
Unordered, periodic flush, high performance
Groups write operations
Transactional
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!
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
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
64
© 2008 Francisco Moya
Keeping servants in memory
●
To avoid trashing critical objects
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
They are recursive, the keep
and the release invocations
must be balanced
Distributed Systems Architecture - Advanced Ice
66
© 2008 Francisco Moya
Compatible with FreezeMaps
–
67
Distributed Systems Architecture - Advanced Ice
Current transaction in the Evictor
●
65
Distributed Systems Architecture - Advanced Ice
TransactionalEvictor
●
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);
};
© 2008 Francisco Moya
63
Distributed Systems Architecture - Advanced Ice
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();
We may mix FreezeMap and TransactionalEvictor
local interface TransactionalEvictor extends Evictor {
Transaction getCurrentTransaction();
void setCurrentTransaction(Transaction tx);
};
Ice.Identity ident = Ice.Util.stringToIdentity("obj1");
if (!e.hasObject(ident)) {
e.add(new RWI(), ident);
}
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
68
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
69
Software distribuido
●
El desarrollo de SW distribuido es diferente
●
¿Dónde están los problemas?
–
Fallos en procesos y en comunicaciones
–
Cuellos de botella en redes de comunicación
●
IceStorm
●
No es posible aislar por completo la lógica de negocio
Puede afectar al propio diseño
–
© 2008 Francisco Moya
70
Distributed Systems Architecture - Advanced Ice
Imprescindible probar tráfico realista cuanto antes
© 2008 Francisco Moya
Cuellos de botella
●
Mal diseño de las interfaces remotas
●
●
–
–
Preferible el envío de datos por lotes
Minimizar las invocaciones
Mala disposición física de servidores
●
●
–
© 2008 Francisco Moya
Envíos por lotes (batching)
Filtrado de eventos
Publica una vez
–
Aplicar principios generales por subsistemas
–
●
Publicador
Aprovechar co-location si es posible
Complejidad inherente al sistema
●
●
IceStorm para desacoplar
Causas muy variadas
–
●
71
Distributed Systems Architecture - Advanced Ice
●
¡IceStorm!
Publicar = invocar método sin valores de retorno
–
72
Distributed Systems Architecture - Advanced Ice
Suscriptores
Propaga a tantos como suscriptores
Solo semántica push
© 2008 Francisco Moya
73
Distributed Systems Architecture - Advanced Ice
IceStorm
IceStorm
Características básicas
Características avanzadas
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
●
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
Link
Topic
© 2008 Francisco Moya
●
●
●
74
Distributed Systems Architecture - Advanced Ice
75
Distributed Systems Architecture - Advanced Ice
IceStorm
IceStorm
Características molestas
Interfaz del TopicManager
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
Distributed Systems Architecture - Advanced Ice
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();
};
};
Posible pérdida de mensajes si no se usan
invocaciones twoway
© 2008 Francisco Moya
© 2008 Francisco Moya
76
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
77
IceStorm
IceStorm
Interfaz del Topic
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);
}
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
78
Distributed Systems Architecture - Advanced Ice
IceStorm
IceStorm
Type safety mediante interfaces Slice
Distributed Systems Architecture - Advanced Ice
80
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
Coste de mensajes y enlaces
●
●
Mensajes solo se propagan un nivel
java.util.HashMap ctx
= new java.util.HashMap();
ctx.put("cost", "5");
consumer.myReport(data, ctx);
●
Distributed Systems Architecture - Advanced Ice
82
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
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());
IceStorm replicado
●
81
Calidad de servicio
●
El peso del enlace limita la propagación a los
mensajes de peso igual o superior
© 2008 Francisco Moya
79
Distributed Systems Architecture - Advanced Ice
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
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
84
© 2008 Francisco Moya
Distributed Systems Architecture - Advanced Ice
83
Related documents