Download Cómputo Distribuido Mediante RMI (R M h d I i R M h d I i ) (Remote
Document related concepts
no text concepts found
Transcript
Modelo de objetos Cómputo Distribuido Mediante RMI (Remote R Method M h d IInvocation) Invocation i ) Modelo de objetos en sistemas distribuidos Máquina q A Máquina q B Máquina C El sueño de todo sistema distribuido Lo ideal sería tener un n sistema distrib distribuido ido orientado a objetos que permita: 1)Invocar un método de un objeto que se localiza en otra máquina q exactamente de la misma manera que si se encontrará en la misma máquina objetoDistante.metodo() Tomado de “Java et les objets distribués”, Patrick Itey, INRIA-Sophia, France El sueño de todo sistema distribuido • 2.- Utilizar un objeto distante (OD), sin saber donde se encuentra simplemente solicitando su dirección a un servicio dedicado: objetoDistante bj t Di t t = ServicioDeNombres.busca("miObjeto"); El sueño de todo sistema distribuido • 3) Poder pasar un OD como parámetro de llamada a un método local ó remoto: resultado = objetoLocal metodo(objetoDistante); objetoLocal.metodo(objetoDistante); resultado lt d = objetoDistante.metodo(otroObjetDistante); Tomado de “Java et les objets distribués”, Patrick Itey, INRIA-Sophia, France El sueño de todo sistema distribuido • 4) Poder recibir como resultado de una invocación un objeto que ha sido creado en una máquina distante: ObjetoDistante = ObjetoDistante.metodo() ; Tomado de “Java et les objets distribués”, Patrick Itey, INRIA-Sophia, France Tomado de “Java et les objets distribués”, Patrick Itey, INRIA-Sophia, France Comunicación entre objetos remotos Java Virtual Machine Client Object Java Virtual Machine TCP Remote Object Arquitectura de Java RMI Las capas de RMI Capa de Aplicación Objeto Servidor Objeto Cliente Java Virtual Machine Java Virtual Machine Client Object j Remote Object j S b Stub Sk l Skeleton Capa de Representantes Stub Skeleton Proxy Referencia Remota Capa de RMI Referencia Remota Capa de Protocolo de Transporte Remote Reference Layer Transport p Layer y Comunicación (TCP/IP) Transporte Remote Reference Layer TCP Transport p Layer y P t l de Protocolos d Bajo B j Nivel Ni l Copyright © 1997 Alex Chaffee Comunicación entre el Cliente y el Servidor Objeto Servidor Objeto Cliente Stub Referencia Remota Solicitud Cliente Respuesta Servidor Skeleton Referencia Remota Transporte a spo te Transporte Arquitectura de Java RMI Capa de Aplicación . Objetos que implementan la aplicación. En general en este nivel se distinguen dos tipos de agentes: los clientes, que son objetos que invocan métodos o hacen peticiones a otros objetos remotos y los servidores, que son objetos que reciben peticiones de otros objetos remotos. remotos Capa de Representantes (Proxy) . En esta capa se encuentran los objetos que actúan como representantes locales de objetos remotos. Se encargan del empaquetado y d desempaquetado t d (marshalling ( h lli y desmarshalling) d h lli ) de d las l iinvocaciones, i argumentos t y resultados de métodos remotos. En RMI existen dos tipos de representantes: los stubs del lado cliente y los skeletons del lado servidor. Capa de Referencias Remotas . En esta capa se realiza la interpretación de las referencias a objetos remotos, las referencias locales a stubs o skeletons se resuelven a sus contrapartes remotas y estos datos, junto con los datos "empaquetados" (marshalled) que contienen las invocaciones o los resultados de invocaciones, invocaciones se pasan a la Capa de Transporte. Capa de Transporte . En esta capa se encuentra el protocolo de comunicación, que se Protocolos de Bajo Nivel encarga de d ttransportar t llos mensajes j que iintercambian t bi llos di distintos ti t objetos. bj t RMI utiliza tili por omisión el protocolo TCP/IP. Tecnología de Objetos Tecnología de Objetos • Polimorfismo • Herencia de tipo Vs Herencia de clase Cliente Clase Interface Tipo Java : implements Java : extends Java : implements p Sub Clase Clase 1 p Sub Tipo Clase 2 Clase 3 Objetos Interface, stub, skeleton Patrón General ppara la Invocación Remota Cliente Remote Interface Servidor Stub Skeleton Infrastructura implements implements • Cli t Client St b Stub Sk l t Skeleton Remote Object j (Server) Copyright © 1997 Alex Chaffee Llamada: – Empacar argumentos – convertir a formato de red – Localizar el servidor – transmitir datos • Servicio: – Recibir datos – Desempacar – Invocar método – Empacar la respuesta – transmitir datos RMI Registry g y • RMI registry g y es un servicio de nombres ubicado en el servidor que permite que los clientes remotos obtener una referencia de un objeto remoto. • Para ejecutar el registry ejecute el comando: – Rmiregistry • El registro utiliza el puerto 1099 por default El Servicio de Nombres en RMI Naming es una clase del paquete de RMI que proporciona i ell servicio i i de d registro i t de d objetos bj t remotos. t • Permite relacionar un nombre tipo URL como por ejemplo: “rmi://host/objectname” con un objeto remoto, //host/ es el nombre (o IP) de la máquina á i ddonde d se ubica bi ell objeto bj t y objectname bj t es un string. ti Si se omite el host se asume que es un objeto local. • Se debe agregar g g un número de ppuerto si el servicio de nombres no fue instalado en el puerto 1099: “rmi://host:1234/objectname” Las 2 maneras de usar Naming Tabla de nombres En el servidor El servidor registra el objeto remoto HelloImp obj = new HelloImpl(); Naming.rebind(“//myhost/HelloServer”, obj); Naming N i “banco” En el cliente El cliente obtiene una referencia del objeto remoto mediante su nombre H ll obj Hello bj = (H (Hello)Naming.lookup(”//myhost/HelloServer”); ll )N i l k (”// h /H ll S ”) Naming.lookup() regresa un tipo Object, por lo que el objeto obtenido debe convertirse a la clase. “ “cuenta1” 1” “cuenta2” Objeto Remoto A Objeto Remoto B Host cs.mty.itesm.mx Objeto Remoto C Uso de la tabla Metodos estáticos de la clase Naming void bind(String, Remote) Binds the name to the specified remote object. lookup(“rmi://cs.mty.itesm.mx/cuenta1”) public String[] list(String) Returns an arrayy of strings g of the URLs in the registry g y Naming Objeto Cliente “banco” “cuenta1” Referencia remota tec.com Objeto Remoto Servidor “cuenta2” Host cs.mty.itesm.mx public Remote lookup(String) Returns the remote object for the URL public void rebind(String, Remote) Rebind the name to a new object; replaces any existing bi di binding public void unbind(String) U bi d th Unbind the name Arquitectura RMI Client Virtual Machine Flujo RMI Server Virtual Machine Client Remote Object 1. El servidor crea el objeto remoto Client Virtual Machine Server Virtual Machine 2. El servidor registra el objeto remoto Client Remote Object j 1 Skeleton Stub Server Skeleton S b Stub Server 2 “Fred” Fred Registry Virtual Machine “F d” “Fred” Registry Virtual Machine Flujo RMI Client Virtual Machine Client Server Virtual Machine Client Virtual Machine Remote 3. El cliente solicita el objeto al Registry Object j 4 El Registry regresa la referencia 4. remota Server Virtual Machine Client Remote Object j 5 7 6 Skeleton S b Stub 3 Flujo RMI S b Stub Server 4 Registry Virtual Machine • RMI permite la comunicación entre objetos situados en máquinas diferentes. diferentes Server 5. El Cliente invoca el método del stub 5 6. El Stub se comunica con el skeleton 7. El Skeleton invoca el método del objeto remoto “F d” “Fred” “F d” “Fred” Interfaces, Objetos y Métodos Remotos Skeleton Registry Virtual Machine Crear Aplicaciones Distribuidas utilizando RMI Cuando se utiliza RMI para desarrollar una aplicación distribuida, g estos p pasos g generales: debemos seguir • Un objeto remoto vive en un Servidor. • Cada objeto j remoto implementa p un interfaz remoto q que especifica cuales métodos pueden ser invocados por los clientes. • Los clientes p pueden invocar métodos remotos casi exactamente igual que se invocan métodos locales. • Diseñar e implementar los componentes de nuestra aplicación distribuida. • C Compilar il llos F Fuentes t y generar stubs. t b • Arrancar la Aplicación. p Diseñar e implementar los componentes de nuestra aplicación li ió distribuida. di t ib id • Definir los Interfaces Remotos. Remotos Una interfaz remota especifica los métodos que pueden ser llamados remotamente por un cliente. Compilar los Fuentes y Generar stubs stubs.. Este es un proceso de dos pasos: En el primer paso, se utiliza el compilador javac para compilar los archivos fuentes de Java. • Implementar los Objetos Remotos. Remotos Los objetos remotos deben implementar uno o varios interfaces remotos. La clase del objeto remoto podría incluir implementaciones de otras interfaces locales o remotas que sólo estarán disponibles localmente). • Implementar los Clientes. Clientes Los clientes que utilizan objetos remotos pueden ser implementados después de haber definido las interfaces remotas. Arrancar la Aplicación Look, a remote object. No, Sire, it is but a local stub. Arrancar la aplicación incluye ejecutar 3 programas: 1) el registro de objetos remotos de RMI, 2)) el servidor y 3) el cliente. Diseñar una Interfaz Remota La interfaz define la parte que será accesible remotamente, esta se define heredando del paquete java.rmi.Remote // Hello.java: EJEMPLO Implementar la Interfaz Remota . A continuación exploraremos la clase que implementa la interfaz Hello, que implementa un objeto remoto. import i t j java.rmi.*; i * public interface Hello extends Remote { public String sayhello() throws RemoteException; } Componentes de la implementación del servidor 1 Declarar los Interfaces Remotos que están siendo Implementados La clase que implementa el servidor se declara como: Esta clase también proporciona el resto del código que configura el programa servidor: un método main que: public class Helloimpl extends UnicastRemoteObject p Hello implements 1) crea un ejemplar del objeto remoto, 2) lo registra con la facilidad de nombrado, y 3) configura un controlador de seguridad UnicastRemoteObject j es una clase definida en el API p público del RMI, que puede ser utilizada como superclase para la implementación de objetos remotos. Componentes de la implementación del servidor 2 Proporcionar una Implementación para cada Método Remoto La clase para un objeto remoto proporciona implementaciones para todos los métodos remotos especificados en los interfaces remotos. La interfaz Hello contiene un solo método remoto, sayhello(), que se implementa de esta forma: public String sayhello () {return "Hello, World!";} Componentes de la implementación del servidor 4 Componentes de la implementación del servidor 3 El método main() del Servidor Este método es utilizado para arrancar el servidor, y, por lo tanto, necesita hacer la inicialización necesaria para prepararse para aceptar llamadas de los clientes. clientes Cómo el método main() se declara static static, no está asociado con ningún objeto, sino con la clase Helloimpl. Componentes de la implementación del servidor 5 Crear e Instalar un Controlador de Seguridad Todos los programas que utilicen RMI deben instalar un controlador de seguridad o el RMI no descargará las clases para los objetos que se reciban como parámetros. El controlador de seguridad determina si el código descargado tiene acceso al sistema de archivos local o puede realizar cualquier l i otra operación i privilegiada. i il i d El servidor utiliza un ejemplo de controlador de seguridad suministrado como parte del RMI, el RMISecurityManager. if (System.getSecurityManager() == null) { System setSecurityManager(new RMISecurityManager()); System.setSecurityManager(new } Poner el Objeto Remoto a Disposición de los Clientes Crear un ejemplar de Helloimpl Helloimpl h= new Helloimpl(); Este constructor llama al constructor de su superclase UnicastRemoteObject, que exporta el objeto recién creado al sistema RMI. RMI Antes de que un llamador pueda invocar un método de un objeto remoto, debe obtener una referencia al objeto remoto. remoto remoto Componentes de la implementación del servidor 6 Programa Servidor public class Helloimpl extends UnicastRemoteObject implements Hello { public Helloimpl() throws RemoteException { super(); } La clase Helloimpl crea un nombre para el objeto con la instrucción: String name = “rmi://localhost/hello"; public String sayhello () { return "Hello, World!"; } Este nombre incluye el nombre del host localhost, en el que se están ejecutando el registro y el objeto remoto, y un nombre hello, que identifica el objeto remoto en el registro. Luego está el código necesario para añadir el nombre al registro RMI que se está ejecutando en el servidor. Esto se hace con la sentencia: public static void main (String args[]) { if (System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager());} try { String name = "//localhost/hello"; Helloimpl h= new helloimpl(); Naming rebind(name h); Naming.rebind(name, System.out.println ("Hello Server ready."); } catch (Exception e) { System.err.println("Exception in helloimpl: " + e.getMessage()); e printStackTrace();} e.printStackTrace();} Naming.rebind(name, h); } } Crear un programa cliente Al igual que el servidor Helloimpl, el cliente empieza instalando un controlador de seguridad. seguridad Esto es necesario porque RMI podría descargar código en el cliente. Después de llamar al controlador de seguridad, el cliente busca el objeto remoto por su nombre en el registro del host remoto usando el método Naming.lookup. Cuando se hace la búsqueda del nombre, el código crea una URL que específica el host donde se está ejecutando el servidor. El nombre pasado en la llamada a Naming.lookup tiene la misma síntaxis URL que el nombre pasado a la llamada Naming.rebind. La busqueda se realiza por su nombre, se obtiene su referencia y luego se llama a sus métodos. métodos Esta operación se realiza de la siguiente manera: String name = “rmi://localhost rmi://localhost /hello /hello"; ; Hello h= (Hello) Naming.lookup (name); Una vez q que se dispone p de la referencia al objeto, j , el cliente p puede invocar métodos exactamente como si el objeto fuese local String message = h.sayHello (); System.out.println ("helloclient : " + message); Programa Cliente Compilación y ejecución import java java.rmi. rmi *;; public class Helloclient { public static void main(String args[]) { Se utiliza el compilador javac para compilar los archivos fuentes de Java, los cuales contienen las implementaciones de los interfaces remotos, las clases del servidor, y del cliente. if (System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); } try { javac Helloclient.java javac Hello.java javac Helloimpl.java String name = "//localhost /hello"; Hello h= (Hello) Naming.lookup (name); String message = h.sayhello(); System.out.println ("helloclient : " + message); } catch (Exception e) { System.out.println ("Exception in main: " + e); } } } Java Policy File Ejecución del programa Una vez compilados y creados los stubs, es necesario ejecutar el registro RMI, que como ya mencionamos permite a los clientes remotos obtener una referencia a un objeto remoto por su nombre. rmiregistry Y por ultimo, ejecutar en otras ventanas el servidor y el cliente • En Java 2, las aplicaciones deben accesar un lista de priviliegios Para esto, priviliegios. esto consultan la política de seguridad (security policy) mediante un archivo (policy file). En el siguiente ejemplo se permiten todos los privilegios ya que el contenido del archivo policy.all policy all es: java -Djava.security.policy=policy.all Helloimpl java -Djava.security.policy=policy.all Djava.security.policy policy.all Helloclient -D es una opcion que permite definir las propiedades del entorno de ejecución (S (System properties) i ) ejemplos: j l Djava.security.policy=/home/bruce/date/policy.all Djava.rmi.server.codebase=file:/home/bruce/date/ j grant { permission java.security.AllPermission; }; ¿Cómo escribir aplicaciones con Java RMI? 1 Definición de la interfaz remota 2 Implementación de la interfaz remota (.java) 3 jjavac (.class) ANEXO 1 Servidor (.class) 4 generación 8 Cliente 9 javac 10 Ejecutar Cliente usa Stub (.class) Skeleton (.class) automática (.java) (.class) CLIENTE 5 Arrancar RMIRegistry 6 Crear los objetos 7 Registrar los objetos SERVIDOR Steps for Developing an RMI System ANEXO 2 1. Define the remote interface 2 Develop the remote object by implementing the remote 2. interface. 3. Develop p the client program. p g 4. Compile the Java source files. 5. Generate the client stubs and server skeletons. 6. Start the RMI registry. 7. Start the remote server objects. 8 R 8. Run th the client li t Step 1: Defining the Remote Interface • To create an RMI application, the first step is the defining of a remote interface between the client and server objects. objects /* SampleServer.java */ import java.rmi.*; public interface SampleServer extends Remote { public int sum(int a,int b) throws RemoteException; } Step 2: Develop the remote object and its interface • Implement the remote methods /* SampleServerImpl.java */ / / public int sum(int a,int b) throws RemoteException { return a + b; } } • The server must bind its name to the registry, registry the client will look up the server name. • Use java.rmi.Naming class to bind the server name to registry. In this example the name call “SAMPLESERVER”. • In I th the main i method th d off your server object, bj t the th RMI security manager is created and installed. Step 2: Develop the remote object and its interface • • • The server is a simple unicast remote server. Create server by y extending g jjava.rmi.server.UnicastRemoteObject j . The server uses the RMISecurityManager to protect its resources while engaging in remote communication. /* SampleServerImpl.java */ import java.rmi.*; import java.rmi.server.*; import java.rmi.registry.*; public class SampleServerImpl extends UnicastRemoteObject implements SampleServer { SampleServerImpl() throws RemoteException { super(); } Step 2: Develop the remote object and its interface /* SampleServerImpl.java */ public static void main(String args[]) { try { System.setSecurityManager(new RMISecurityManager()); //set the security manager //create a local instance of the object SampleServerImpl Server = new SampleServerImpl(); //put the local instance in the registry Naming.rebind("SAMPLE-SERVER" , Server); System.out.println("Server waiting....."); } catch (java.net.MalformedURLException me) { System.out.println("Malformed URL: " + me.toString()); } catch (RemoteException re) { System out println("Remote exception: " + re System.out.println("Remote re.toString()); toString()); } } Step 3: Develop the client program • In order for the client object to invoke methods on the server it must first look up the name of server in the server, registry. You use the java.rmi.Naming class to lookup the server name. • The server name is specified as URL in the from ( rmi://host:port/name ) • Default RMI port is 1099. 1099 • The name specified in the URL must exactly match the name that the server has bound to the registry. In this example, the name is “SAMPLE-SERVER” • The remote method invocation is programmed using the remote interface name (remoteObject) as prefix and the remote method name (sum) as suffix. Step 4 & 5: Compile the Java source files > javac SampleServer SampleServer.java java > javac SampleServerImpl.java > j javac SampleClient.java p j Step 3: Develop the client program import java.rmi.*; public class SampleClient { public static void main(String[] args) { // set the security manager for the client System.setSecurityManager(new RMISecurityManager()); //get the remote object from the registry try tr { System.out.println("Security Manager loaded"); String url = "//localhost/SAMPLE-SERVER"; SampleServer remoteObject = (SampleServer)Naming.lookup(url); System.out.println("Got remote object"); System.out.println(" 1 + 2 = " + remoteObject.sum(1,2) ); } catch (RemoteException exc) { S t System.out.println("Error t i tl ("E i in l lookup: k " + exc.toString()); t St i ()) } catch (java.net.MalformedURLException exc) { System.out.println("Malformed URL: " + exc.toString()); } catch (java.rmi.NotBoundException exc) { System.out.println("NotBound: y p " + exc.toString()); g } } } Step 6: Start the RMI registry • The RMI applications need install to Registry. And the R i t mustt start Registry t t manuall by b call ll rmiregisty. i i • The rmiregistry us uses port 1099 by default. You can also bind rmiregistry to a different port by indicating the new port number as : rmiregistry <new port> > rmiregistry i i t • Remark: On Windows,, yyou have to type yp in from f the command line: > start rmiregistry Steps 7 & 8: Start the remote server objects & Run the client • Once the Registry is started, the server can be started and will ill be b able bl to store itself i lf in i the h Registry. R i • Because of the grained security model in Java 2.0, you must setup a security policy for RMI by set java.security.policy to the file policy.all > java –Djava.security.policy=policy.all –Djava security policy=policy all SampleServerImpl > java –Djava.security.policy=policy.all Djava.security.policy policy.all SampleClient Java Policy File 2 Now, we given an example for assigning resource permissions: grant { permission java java.io.filePermission io filePermission “/tmp/*” /tmp/* , “read” read , “write”; write ; permission java.net.SocketPermission , ; “somehost.somedomain.com:999”,”connect”; permission java.net.SocketPermission “*:1024-65535”,”connect,request”; permission java.net.SocketPermission “*:80”,”connect”; }; Java Policy File • In Java 2, the java application must first obtain information regarding its privileges. privileges It can obtain the security policy through a policy file. In above example, we allow Java code to have all permissions, the contains of the policy file policy all is: policy.all grant { permission java.security.AllPermission; };