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