Download - Diapositivas del Tema 7
1
CONTENIDO:
Conceptos de Programación DistribuidaRemote Method Invocation (RMI) en JavaEl Nivel de ResguardosLa Responsable de que Todo Funcione: la interfazEl precompilador rmicArquitectura Completa de una AplicaciónEvoluciones Reseñables
BIBLIOGRAFÍA:
[Eck02] Eckel, B. Piensa en Java. Prentice Hall, 2002. [Hil00] Hilderink et al. Communicating Threads for Java. Draft.[Vin97] Vinoski, S. CORBA: Integrating Diverse…IEEE
Communications Magazine, vol. 35, nº 2, February, 1997.[Gro01] Grosso, W. Java RMI. O’Reilly, 2001.
TEMA 7: Paso de Mensajes con RMI
2
No existe memoria comúnComunicacionesNo existe un estado global del sistemaGrado de TransparenciaEscalablesReconfigurables
Conceptos de ProgramaciConceptos de Programacióón Distribuidan Distribuida
3
Modelo de Paso de MensajesOperaciones send y receive
Modelo RPCStubs de cliente y servidorVisión en Java es RMI
Modelos de Objetos DistribuidosDCOM de MicrosoftJini de SunCORBA de OMG
Modelos de ProgramaciModelos de Programacióón Distribuidan Distribuida
4
Mecanismo para comunicar y sincronizar entidades concurrentes que no pueden o no quieren compartir memoriaLlamadas send y receiveTipología de las llamadas:
Bloqueadas-No bloqueadasAlmacenadas-No almacenadas (en buffer)Fiables-No Fiables
En Unix:Pipes con y sin nombre
En Java:Sockets: Clases Socket y ServerSocketCanales: CTJ (Communicating Threads for Java)
Modelo de Paso de MensajesModelo de Paso de Mensajes
5
NUCLEO NUCLEO
CLIENTE SERVIDOR
SOLICITUD
RESPUESTA
RED
Modelo General
6
Puertos (Breve repaso)
El protocolo TCP (y también UDP) utilizan los puertos para hacer llegar los datos de entrada a un proceso concreto que se ejecuta en una máquina
SERVIDOR
PUERTO
CLIENTE
TCP/UDP
7
SERVIDOR
PUERTO
CLIENTE
Solicitud de conexión
SERVIDOR
PUERTO
CLIENTE
PUERTO
PUERTO
8
Mayor nivel de abstracciónLlamadas a procedimiento local o remoto indistintamenteNecesita de stubs/skeletons (¡OCULTAMIENTO!)Registro del servicio (Servidor de Nombres)En Unix:
Biblioteca rpc.hRepresentación estándar XDRAutomatización parcial: especificación-compilador rpcgen
En Java:Objetos remotos. SerializaciónPaquete java.rmiAutomatización parcial: interfaz-compilador rmic
Modelo Remote Procedure Call (RPC)Modelo Remote Procedure Call (RPC)
9Host local
Espacio del usuario
Programa cliente
Espacio del usuario
Programa servidor
func() func(void){//codigo………….}
Host remoto
Llamando a un procedimiento remoto
OBJETIVOS:1.Efectuar la llamada como si tuviera carácter local2.Enmascarar aspectos relativos a comunicaciones3.¿Y cómo lograrlo…?
10
Introducción del nivel de stubs
Efectúan el marshalling/unmarshalling de parámetros.Bloquean al cliente a la espera del resultado.Transparencia de ejecución remotaInterface con el nivel de red.
TCPUDP
11
Servicios de Red
Programa Cliente
Stub del Cliente
Proceso Cliente
callrpcrpcreturn
Servicios de Red
Stub del Servidor
Funciones Servidor
Proceso Servidor
llamadanormal return
RED
Esquema RPC con stubs
Núcleo Cliente Núcleo Servidor
12
¿Y cómo generar los stubs?
De forma manualDe forma automática
Especificación formal de interfazSoftware específicorpcgen (C-unix)/rmic (Java)
13
Especificación FormalInterface
Precompiladorrpcgen o rmic
ResguardoStub
ResguardoSkeleton
Ficheros compartidos
Representaciónde datosCliente Servidor
COMPILAR
COMPILAR
ClienteEjecutable
ServidorEjecutable
Generación automática de stubs
14
Especificación FormalInterface
Generadorde
Resguardos
Res. Del Servidor Res. Del Cliente
SERVIDOR CLIENTECONECTOR
Interfaz delservidor+asacreate, readdelete, write
Petición de asa del servidor Envío de asa
Read(f,d)
d
Dinamic Dinamic BindingBinding
15
Breve Nota sobre RPC en C
Especificación de la interfaz del servidor remoto en un fichero de especificación .x
/*rand.x*/program RAND_PROG{
version RAND_VER{void inicia_aleatorio(long)=1;double obtener_aleat(void)=2;
}=1;}=0x3111111;
Generación autómática de resguardos: $rpcgen rand.xDistribuir y compilar ficheros entre las máquinas implicadasNecesario utilizar representación XDR. Biblioteca xdr.h
16
RMI (Remote Method Invocation) en JavaRMI (Remote Method Invocation) en Java
ObjetoCliente
JVM
ObjetoServidor
JVM
Permite disponer de objetos distribuidos utilizando JavaUn objeto distribuido se ejecuta en una JVM diferente o remotaObjetivo: lograr una referencia al objeto remoto que permita utilizarlo como si el objeto se estuviera ejecutando sobre la JVM localEs similar a RPC, si bien el nivel de abstracción es más altoSe puede generalizar a otros lenguajes utilizando JNIRMI pasa los parámetros y valores de retorno utilizando serializaciónde objetos.
17
RPC versus RMI
RPC RMICarácter y Estructura de diseño procedimental
Carácter y Estructura de diseño orientada a objetos
Es dependiente del lenguaje Es dependiente del lenguaje
Utiliza la representación externa de datos XDR
Utiliza la serialización de objetos en Java
El uso de punteros requiere el manejo explícito de los mismos
El uso de referencias a objetos locales y remotos es automático
NO hay movilidad de código El código es móvil, mediante el uso de bytecodes.
18
Llamadas locales vs. Llamadas remotas
Un objeto remoto es aquél que se ejecuta en una JVM diferente, situada potencialmente en un host distinto.RMI es la acción de invocar a un método de la interfaz de un objeto remoto.
//ejemplo de llamada a método local
int dato;
dato = Suma (x,y);
//ejemplo de llamada a método remoto (no completo)
IEjemploRMI1 ORemoto = (IEjemploRMI1)Naming.lookup(“//sargo:2005/EjemploRMI1”);
ORemoto.Suma(x,y);
19
Arquitectura RMI
Cliente Servidor
Stub Skeleton
ReferenciaRemota
ReferenciaRemota
TransporteTransporte
El servidor debe extender RemoteObjectEl servidor debe implementar una interfazdiseñada previamenteEl servidor debe tener como mínimo unconstructor (nulo) que lanzará la excepciónRemoteExceptionEl método main del servidor debe lanzarun gestor de seguridadEl método main crea los objetos remotosEl compilador de RMI (rmic) genera el stuby el skeleton.Los clientes de objetos remotos se comunicancon interfaces remotas (diseñadas antes de…)Los objetos remotos son pasados por referenciaLos clientes que llaman a métodos remotosdeben manejar excepciones.
20
La clase java.rmi.Naming
public static void bind(String name, Remote obj)
public static String[] list(String name)
public static Remote lookup(String name)
public static void rebind(String name, Remote obj)
public static void unbind(String name)
21
¿Cómo lograrlo?public interfazextends Remote
{signaturas métodos}
Implementaciónde la interfaz
Cliente
SERVIDOR
implements
new
Nombre Referencia
servicio ref bind ó rebindlookup
referencia a interfaz
ref.metodo(param)
resultado
22
Definir Interfaz Remotaimplements
Implementar InterfazRemota
$ rmic .class
SkeletonStub
JVM
Implementar Cliente
JVM
Implementar Servidor
23
FASES DE DISEÑO RMI (1-INTERFACE)Escribir el fichero de la interfaz remota. Debe ser public y extender a Remote.Declara todos los métodos que el servidor remoto ofrece, pero NO losimplementa. Se indica nombre, parámetros y tipo de retorno.Todos los métodos de la interfaz remota lanzan obligatoriamente la excepción RemoteExceptionEl propósito de la interface es ocultar la implementación de los aspectos relativos a los métodos remotos.De esta forma, cuando el cliente logra una referencia a un objeto remoto, en realidad obtiene una referencia a una interfaz.Los clientes envían sus mensaje a los métodos de la interfaz
24
EJEMPLO (FICHERO DE INTERFAZ)
/**Ejemplo del interfaz remoto para implementar un RMI* @author Antonio Tomeu*Es un servidor remoto aritmético.*/
//se importan las clases del paquete rmi import java.rmi.*;
//toda interface remota debe extender la clase Remotepublic interface IEjemploRMI1 extends Remote{//todo metodo de la interfaz remota debe lanzar la //excepcion RemoteExceptionint Suma(int x, int y) throws RemoteException; int Resta(int x, int y) throws RemoteException; int Producto(int x, int y) throws RemoteException; float Cociente(int x, int y) throws RemoteException;
}
25
La implementación del servidor es un fichero que realiza la implementación de la interfaz definida previamente.El servidor debe contener una clase que extienda a UnicasRemoteObject.
Esa misma clase debe implementar a la interfaz remota (implements)
Debe tener un constructor que lance RemoteException.El método main debe lanzar un gestor de seguridad.El método main debe crear los objetos remotos deseados.El método main debe registrar al menos unos de los objetos remotos.
FASES DE DISEÑO RMI (2-IMPLEMENTACIÓN)
26
EJEMPLO (IMPLEMENTACIÓN DE INTERFAZ Y SERVIDOR)
/**Ejemplo de implementacion del interfaz remoto para un RMI* @author Antonio Tomeu*/
//se importan los paquetes necesariosimport java.rmi.*;import java.rmi.server.*;import java.rmi.registry.*;import java.net.*;
//el servidor debe siempre extender a UnicastRemoteObject//el servidor debe simpre implementar la interfaz remota
public class EjemploRMI1extends UnicastRemoteObjectimplements IEjemploRMI1
{
27
//aquí viene la implementación de los métodos que se //declararon en la interfaz
public int Suma(int x, int y)throws RemoteException{return x+y;}
public int Resta(int x, int y)throws RemoteException{return x-y;}
public int Producto(int x, int y)throws RemoteException{return x*y;}
public float Cociente(int x, int y)throws RemoteException{ if(y == 0) return 1;else return x/y;
}//a continuacion viene el codigo del servidor. Hemos optado //por incluirlo de manera conjunta, pero podia haber ido en//un fichero aparte.
28
//es necesario que haya un constructor (nulo) como minimo, ya //que debe lanzar RemoteExceptionpublic EjemploRMI1()
throws RemoteException{//super();}
//el metodo main siguiente realiza el registro del servicio
public static void main(String[] args)throws Exception
{//crea e instala un gestor de seguridad que soporte RMI.//el usado es distribuido con JDK. Otros son posibles.System.setSecurityManager(new RMISecurityManager());
//Se crea el objeto remoto. Podriamos crear mas si interesa.EjemploRMI1 ORemoto = new EjemploRMI1();//Se registra el objeto en la máquina remota. No hay que dar//nombre de host, y se asume el puerto 1099.Naming.bind(“Servidor",ORemoto);System.out.println("Servidor Remoto Preparado");
}}
29
FASES DE DISEÑO RMI (3- Generando STUB Y SKELETON)
Compilador de RMI$ rmic imp
Fichero de implementación
de Interfaz compilado
(Imp.class)
Fichero de stub
(Imp_Stub.class)
Fichero de skeleton
(Imp_Skel.class)
$ rmic –vcompat EjemploRMI1
Es necesario que en la máquina remota donde se aloje el servidor se sitúen tambiénlos ficheros de stub y skeleton. (Cambios a partir de 1.5)Con todo ello disponible, se lanza el servidor llamando a JVM del host remoto, previo registro en un DNSEn nuestro caso, el servidor remoto se activó en hercules.uca.es sobre el puerto 1099.
$ java EjemploRMI1 &
30
FASES DE DISEÑO RMI (4-REGISTRO)
Método Naming.bind(“Servidor",ORemoto);para registrar el objeto remoto creado requiere que el servidor
de nombres esté activo. Dicho servidor se activa con start rmiregistry en Win32 Dicho servidor se activa con rmiregistry & en Unix.Se puede indicar como parámetro el puerto que escucha.Si no se indica, por defecto es el puerto 1099.El parámetro puede ser el nombre de un host como en
Naming.bind(“//sargo.uca.es:2005/Servidor",ORemoto);
31
El objeto cliente procede siempre creando un objeto de interfaz remota. Posteriormente efectúa una llamada al método Naming.lookup cuyo parámetro es el nombre y puerto del host remoto junto con el nombre del servidor.Naming.lookup devuelve una referencia que se convierte a una referencia a la interfaz remota.A partir de aquí, a través de esa referencia el programador puede invocar todos los métodos de esa interfaz remota como si fueran referencias a objetos en la JVM local.
FASES DE DISEÑO RMI (5-CLIENTE)
32
/**Ejemplo de implementacion de un cliente para RMI* @author Antonio Tomeu*/
import java.rmi.*;import java.rmi.registry.*;public class ClienteEjemploRMI1{public static void main(String[] args) throws Exception{int a = 10;int b = -10;//Se obtiene una referencia a la interfaz del objeto remoto//SIEMPRE debe convertirse el retorno del metodo Naming.lookup//a un objeto de interfaz remoto IEjemploRMI1 RefObRemoto =
(IEjemploRMI1)Naming.lookup("//hercules.uca.es/Servidor");//Llamamos a los metodos del interfaz remoto.System.out.println(RefObRemoto.Suma(a,b));System.out.println(RefObRemoto.Resta(a,b));System.out.println(RefObRemoto.Producto(a,b));System.out.println(RefObRemoto.Cociente(a,b));
}}
EJEMPLO (CLIENTE)
33
Distribución de Archivos
Interfaz.class
Cliente.class
Implem_Stub.class
Interfaz.class
Servidor.class
Implem_Stub.class
Implem_Skel.class
ServidorCliente
NOTA: A PARTIR DE jdk 1.2 LAS CLASES DE SKELETON NO SON NECESARIAS
34
EJERCICIODescargue los ficheros IEjemploRMI1.java, EjemploRMI1.java y ClienteEjemploRMI1.javaSiga el guión auxiliar de prácticas (ver bloque del tema actual) y desarrolle la arquitectura en localDistribuya ahora la aplicación con un compañeroEscriba una interfaz de operaciones para números complejos, utilizando tipos primitivos, llamada IComplejo.java
Impleméntela en Complejo.javaEscriba código de servidor y cliente que hagan uso de la misma. Guárdelos en ServerComplejo.java y ClientComplejo.java
Distribuya nuevamente la aplicación
35
Acuerden una interfaz llamada interfaz_grupo_x.javaUn miembro del grupo escribirá el cliente_grupo_java y el otro el servidor_grupo_x.java de manera independiente. Una vez hecho, lancen la arquitectura rmi.Suban el Espacio de los alumnos un fichero rmi_grupo_x.rar que contegan los tres ficheros.
36
EVOLUCIONES RESEÑABLES
A partir del jdk 1.2 la implementación de RMI no necesita skeletons (con ese nombre tenían poco futuro). El stub estaráen ambos lados.Recompile los ejemplos anteriores sin el flag –vcompatA partir del jdk 1.5 se incorpora Generación Dinámica de Resguardos
37
EJERCICIOS
Pruebe los ejemplos anteriores sin skeletonNo obstante, ¿necesita el servidor algo a pesar de todo ?
38
RMI: CARACTERÍSTICAS AVANZADAS
Serialización de ObjetosGestión de la Seguridad: policytoolCallback de ClienteDescarga Dinámica de Clases
39
SERIALIZACIÓN: La interfaz Serializable
Serializar un objeto es convertirlo en una cadena de bits, posteriormente restaurada en el objeto original
Es útil para enviar objetos complejos en RMITipos primitivos se serializan autómaticamenteClases contenedoras tambiénObjetos complejos deben implementar la interfaz
Serializable (es un flag) para poder ser serializados
40
Ejemplo con serialización de una clase
import java.io.*;import java.util.*;
public class cuentabancaimplements Serializable{ int ccc; float saldo; String Titular;
public cuentabanca(int codigo, float deposito, String nombre)
{ccc = codigo; saldo = deposito; Titular = nombre;}
public String toString(){return("codigo = "+ccc+" saldo= "+saldo+" titular=
"+Titular);}}
41
import java.io.*;import java.rmi.*;public interface intefaz
extends Remote{
boolean deposito(int codigo, float cantidad) throws RemoteException;
boolean reintegro(int codigo, float cantidad) throws RemoteException;
String nomtit(int codigo) throws RemoteException;
int codtit(String nom) throws RemoteException;/aquí la serializacion es necesaria*/cuentabanca [] listado() throws RemoteException;
}
Interfaz
42
public class Arbol implements java.io.Serializable //convierte a la clase en serializable
{public Arbol izq;public Arbol der;public int id;public int nivel;private static int cont = 0;
public Arbol(int l) {id = cont++;nivel = l;if (l > 0) {
izq = new Arbol(l-1);der = new Arbol(l-1);
}}
}
Ejemplo completo con serialización (1/4)
43
//interfaz que transfiere al servidor una instancia de laclase serializable Arbol.java
import java.rmi.*;public interface IArbol
extends Remote{
public void Listado_Remoto (Arbol t, int n) throws RemoteException;
}
Ejemplo completo con serialización (2/4)
44
import java.rmi.*;import java.rmi.server.*;import java.rmi.registry.*;
public class Serv_arbolextends UnicastRemoteObject implements IArbol
{public Serv_arbol()throws RemoteException{super();}
public void Listado_Remoto (Arbol t, int n) throws RemoteException{for (int i = 0; i < t.nivel; i++)System.out.print(" ");System.out.println("nodo " + t.id);if (t.nivel <= n && t.izq != null) Listado_Remoto(t.izq, n);if (t.nivel <= n && t.der != null) Listado_Remoto(t.der, n);
}public static void main(String[] args) throws Exception{Serv_arbol ORemoto = new Serv_arbol();Naming.bind("Servidor", ORemoto);System.out.println("Servidor Remoto Preparado");
}}
Ejemplo completo con serialización (3/4)
45
import java.rmi.*;import java.rmi.registry.*;
public class Client_arbol{
public static void main(String[] args)throws Exception
{int niveles = 3;Arbol arb = new Arbol (niveles); //se crea un objeto serializable
IArbol RefObRemoto = (IArbol)Naming.lookup("//localhost/Servidor");
RefObRemoto.Listado_Remoto (arb, niveles); //transfiere al objeto//servidor un objeto Arbol //serializado
}}
Ejemplo completo con serialización (4/4)
46
Ejecución del ejemplo en modo local
47
Descargue los ficheros contenidos en la subcarpeta Serializacion (carpeta de códigos del tema), compile y pruebeHaga lo propio distribuyendo la aplicación con un compañero
EJERCICIOS
48
Gestionando la seguridad: policytool
Java tiene en cuenta la seguridadSystem.setSecurityManager(new RMISecurityManager());
Se ajusta la seguridad:Construyendo un objeto SecurityManagerLlamando al método setSecurityManager (clase System)
Clase RMISecurityManagerProgramador ajusta la seguridad mediante la clase Policy
Policy.getPolicy() permite conocer la seguridad actual.Policy.setPolicy() permite fijar nueva política.Seguridad reside en fichero específico.
Java2 incorpora una herramienta visual: policytool
49
Ajuste de la política de seguridadCrearlas con policytool: ejemplo de fichero .policy/* AUTOMATICALLY GENERATED ON Fri May 28 19:23:13 CEST 2004*/
/* DO NOT EDIT */grant {
permission java.net.SocketPermission "*:1024-65535", "connect,accept, listen, accept, connect, listen, resolve";permission java.net.SocketPermission "*:80", "connect, accept";permission java.security.AllPermission;
};Activarlas
Ejecutar ajustando la política con Java –Djava.security=fichero.policy
servidor|clienteO bien crear objeto RMISecurityManager y ajustar SetSecurityManager sobre el objeto creado.
50
CallBack de Cliente
Si servidor de RMI debe notificar eventos a clientes, la arquitectura es inapropiadaLa alternativa estándar es el sondeo (polling)Donde cliente:
Iservidor RefRemota= (IServidor) Naming.lookup (URL);
while (!(Ref.Remota.Evento.Esperado())){}
51
import java.rmi.*;public interface ejemploPollingextends Remote{
public void datoInc() throws RemoteException;public boolean igualDiez() throws RemoteException;//metodo para realizar el sondeo continuo sobre el servidor
}
RMI con Polling: Ejemplo de interfaz
52
import java.rmi.*;import java.rmi.server.*;import java.rmi.registry.*;
public class servPolling extends UnicastRemoteObjectimplements ejemploPolling
{private static int dato = 0;
public void datoInc() throws RemoteException{dato++; System.out.println(dato);}
public boolean igualDiez() throws RemoteException //metodo para recibir el sondeo{return (dato==10);}
public servPolling() throws RemoteException {}
public static void main(String[] args) throws Exception
{servPolling contRemoto = new servPolling(); Naming.bind("Servidor_Polling", contRemoto);System.out.println("Servidor Remoto Preparado");
}}
RMI con Polling: Ejemplo de servidor
53
import java.rmi.*;import java.rmi.registry.*;
public class clientPolling {
public static void main(String[] args) throws Exception
{ejemploPolling RefObRemoto = (ejemploPolling)Naming.lookup("//localhost/Servidor_Polling");
while(!RefObRemoto.igualDiez()) //lazo de sondeo continuo al sevidor…{System.out.println("Incremento remoto del contador");RefObRemoto.datoInc();
}System.out.print("El contador remoto llego a diez y se sale...");
}}
RMI con Polling: Ejemplo de cliente
54
Características del CallBack
Clientes interesados se registran en un objeto servidor para que les sea notificado un eventoCuando el evento se produce, el objeto servidor notifica al cliente su ocurrencia¿Qué necesitamos para que funcione?
55
Arquitectura RMI para CallBack
56
Hay que duplicar la arquitecturaSe requieren dos interfacesHabrá dos niveles de stubs
Cliente (Stub+Skel) y Servidor (Stub+Skel)Es necesario proveer en el servidor medios para que los clientes registren sus peticiones de callback
Conclusiones
57
EJERCICIOS
Lea el guión de callback de clienteCompile y active el código ejemplo de callback que figura en la subcarpeta callback de la carpeta codigos rmi (utilice stubs y skeletons)Haga lo propio con subcarpeta callback_simpelDistribuya la aplicación con su compañero de grupo
58
Descarga Dinámica de Clases
Permite cambios libres en el servidorElimina la necesidad de distribuir (resguardos) si los hay y nuevas clasesDinámicamente, el cliente descarga todas las clases que necesita para desarrollar una RMI válidaMediante HTTP o incluso FTP
59
Cliente de RMI
Registro de RMI
ServidorRMI
server.codebase=http://host/directorio
Localización URLhttp
host
(1)Servidor registra el par(Objeto, nombre)
(2)Cliente solicita interfazvía Naming.lookup
(3)Registro ofrece una referencia remota
(4)Cliente solicita la clase de stubmediante el codebase
(5)Servidor http devuelvela clase de stub
60
Servidor HTTP para Descarga Dinámica
Mini-servidor de HTTP de SunClases ClassServer y ClassFileServerSe compilan conjuntamentejava ClassFileServer 8080 /rmi/clases
Servidor HTTP estándarApacheOtros
61
Ejemplo del Servidor Básico de Sun activo en WindowsColocar Resguardos y clases para carga dinámica en /java/rmiAjustar la propiedad java.rmi.server.codebase
62
Novedades a partir de jdk 1.5
Soporta Generación Dinámica de ResguardosPrescinde del generador rmicPruebe ahora los ejemplos anteriores sin pasar por la etapa de generación de resguardos (rmic) ¿qué observa?