RPC: Remote Procedure Calls LSUB GSYC 15 de abril de 2015 (cc) 2015 Laboratorio de Sistemas, Algunos derechos reservados. Este trabajo se entrega bajo la licencia Creative Commons Reconocimiento NoComercial - SinObraDerivada (by-nc-nd). Para obtener la licencia completa, véase http://creativecommons.org/licenses/. También puede solicitarse a Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. Las imágenes de terceros conservan su licencia original. RPC • Llamada a un procedimiento que ejecuta en otro espacio de direcciones. • Objetivo: enmascarar un llamada remota como una llamada a un procedimiento local. • Sigue el modelo cliente/servidor, petición-respuesta. • Pueden ser sı́ncronas o ası́ncronas. • Middleware: capa de software que permite realizar RPCs ocultando los detalles de la comunicación y de la distribución: transparencia de acceso y de distribución. ecución de una RPC RPC PC involucra una serie de etapas que se ejecutan tanto en la máquina que realiza omo en la máquina que ejecuta el procedimiento remoto (servidor). Figura 2: Pasos en la ejecución de una RPC RPC: fallos ¿Y si el servidor falla mientras se está haciendo? Hay distintas semánticas: • At most once: la operación se ejecuta como mucho una vez, pero puede que ninguna. Se retorna error al cliente, que no puede saber si se ha realizado la operación o no. • At least once: la operacion se ejecuta al menos una vez, puede que varias. Si la operación es idempotente no hay problema. • Exactly once: la operación se realiza exactamente una vez. En general, es muy complicado (mecanismos de tolerancia a fallos). RPC: Nombrado • Necesitamos nombrar los recursos para poder acceder a ellos (p. ej. hacer una RPC sobre un recurso concreto). • Transparencia de localización: permite encontrar los recursos con independencia de su localización fı́sica. • El servicio puede ser centralizado o distribuido. • El esquema de nombrado puede ser plano o estructurado. RPC: Serialización Serialización o aplanado: • Necesitamos transmitir los datos por la red con un formato dado. • Datos binarios (enteros, floats, etc.), texto, colecciones, referencias a otros objetos... • ¿Interoperabilidad? Serialización en Java • Cliente y servidor (ambos en Java) se pueden despreocupar del formato de los datos. Problema: ambos deben ser programas en Java. • Una clase que cumpla con la interfaz Serializable se puede serializar. Esa interfaz no tiene ningún método. • Aplana el objeto y todos los objetos referenciados (web of objects). • Todas las clases involucradas tienen que implementar Serializable. Serialización en Java • Hay que poner una constante serialVersionUID a la clase. Esta constante sirve para verificar en el desaplanado que las clases que tiene el receptor son compatibles con las clases que tiene el emisor. Debemos cambiarla si modificamos la estructura de la clase. • Si un miembro es transient no forma parte del estado persistente del objeto y no se serializa. • Tampoco se serializan los miembros de clase (static). • Si un objeto no se puede serializar, se levanta la excepción NotSerializableException. Código F i g u r e s = new S q u a r e ( p1 , p2 ) ; ObjectOutputStream os = new O b j e c t O u t p u t S t r e a m ( s o c k . g e t O u t p u t S t r e a m ( ) ) ; os . w r i t e O b j e c t ( s ) ; Serialización en Java Las clases que necesitan personalizar la serialización deben redefinir ciertos métodos como: p r i v a t e void w r i t e O b j e c t ( j a v a . i o . ObjectOutputStream out ) throws IOException private void readObject ( java . io . ObjectInputStream in ) throws IOException , ClassNotFoundException ; Serialización • Pero las máquinas del sistema distribuido pueden ser heterogéneas (hardware y software). • En este caso, tiene que haber una representación canónica para los datos. • Cada extremo debe convertir los datos de su formato local al formato canónico y viceversa: serialización (marshalling o aplanado). • Podemos definir nuestra propia serialización o usar uno de los múltiples estándars: XDR (Sun rpc), JSON, ASN.1, XML-RPC, etc. Ejemplo: JSON • Es un formato de texto. • Es independiente del lenguaje. • Permite aplanar: • Una colección de pares atributo/valor con el que se pueden serializar objetos, records, diccionarios, etc. • Lista de valores con el que se pueden aplanar arrays, listas, conjuntos, etc. Ejemplo: JSON Objeto: { ” rectangulo ” : { ” v i s i b l e ” : true , ” color ” : ” verde ” , ” supIzq ” : { ”x” : 34 , ” y ” : 30 }, ” infDer ” : { ”x” : 43 , ” y ” : 10 } } } Ejemplo: JSON Lista: { ”listaCoor”: [ {”x” : 0 , ”y” : 0} , {”x” : 2 , ”y” : 1} , {”x” : 4 , ”y” : 5} , {”x” : 0 , ”y” : 1} , { ” x ” : −1 , ” y ” : 23} ] } Serialización Para realizar nuestra propia serialización tenemos dos alternativas: • Texto. Factores a tener en cuenta: • Codificación (p. ej. UTF-8). • Terminación de las cadenas. • Binario. Factores a tener en cuenta: • Longitud de los datos. • Endianess. • Formato (p. ej: coma flotante IEEE 754, IEEE 754-2008, etc.). RPC c imagen OOO Program Verification Systems Serialización Ejemplo: serializar un array de 3 enteros : 1, -2, 3. • Texto (UTF-8): "[[1], [-2], [3]]" • Binario (little endian, 4 bytes por entero, complemento a 2): 0x03 0x01 0xfe 0x03 0x00 0x00 0xff 0x00 0x00 0x00 0xff 0x00 0x00 0x00 0xff 0x00 Ejemplo: aplanar un Integer positivo Formato de red: little-endian, 32-bit. private final static int INTSIZE = 4 ; p u b l i c s t a t i c byte [ ] m a r s h a l l ( i n t b y t e r [ ] = new b y t e [ INTSIZE ] ; r [ 3 ] = ( b y t e ) ( i >>24 & 0 x f f ) ; r [ 2 ] = ( b y t e ) ( i >>16 & 0 x f f ) ; r [ 1 ] = ( b y t e ) ( i >>8 & 0 x f f ) ; r [ 0 ] = ( byte ) ( i & 0 x f f ) ; return r ; } i ) throws Exception { Ejemplo: desaplanar un Integer Formato de red: little-endian, 32-bit. private final static int INTSIZE = 4 ; p u b l i c s t a t i c i n t g e t I n t ( B y t e B u f f e r b ) throws Exception { int n; i f ( b . c a p a c i t y ( ) < INTSIZE ) throw new E x c e p t i o n ( ”Bad a r r a y l e n g t h : must ” + ” be g r e a t e r o r e q u a l t o ” + INTSIZE ) ; b . o r d e r ( B y t e O r d e r . LITTLE ENDIAN ) ; n = b. getInt (); return n ; } Ejemplo: aplanar un String Formato de red: UTF-8, tamaño + null-terminated. public byte int byte static [] b = size = [] r = byte [ ] m a r s h a l l ( S t r i n g s ) throws Exception { s . g e t B y t e s ( ”UTF−8” ) ; b . length + 1; new b y t e [ s i z e+INTSIZE ] ; System . a r r a y c o p y ( m a r s h a l l ( s i z e ) , 0 , r , 0 , INTSIZE ) ; System . a r r a y c o p y ( b , 0 , r , INTSIZE , s i z e −1); r [ INTSIZE+s i z e −1] = ( b y t e ) 0 ; return r ; } Ejemplo: desaplanar un String Formato de red: UTF-8, tamaño + null-terminated. p u b l i c s t a t i c S t r i n g g e t S t r ( B y t e B u f f e r b ) throws Exception { int sz = b . getInt ( ) ; b y t e b u f [ ] = new b y t e [ s z − 1 ] ; /∗ i g n o r e t h e n u l l c h a r ∗/ b . get ( buf ) ; b . g e t ( ) ; /∗ s k i p t h e n u l l c h a r ∗/ r e t u r n new S t r i n g ( buf , ”UTF−8” ) ; } Ejemplo: aplanar un array de Integer p u b l i c s t a t i c byte [ ] m a r s h a l l ( i n t [ ] a r r ) throws Exception { b y t e r [ ] = new b y t e [ INTSIZE + INTSIZE ∗ a r r . l e n g t h ] ; i n t pos = 0 ; System . a r r a y c o p y ( m a r s h a l l ( a r r . l e n g t h ) , 0 , r , pos , INTSIZE ) ; p o s += INTSIZE ; f o r ( i n t i : a r r ){ System . a r r a y c o p y ( m a r s h a l l ( i ) , 0 , r , pos , INTSIZE ) ; p o s += INTSIZE ; } return r ; } Ejemplo: desaplanar un array de Integer public s t a t i c Integer [ ] getIntArr ( ByteBuffer b) throws Exception { I n t e g e r n el em = g e t I n t ( b ) ; i f ( ne le m < 0 ) throw new E x c e p t i o n ( ”Bad a r r a y l e n , n e g a t i v e ” ) ; I n t e g e r [ ] a r r = new I n t e g e r [ n el em ] ; f o r ( i n t i = 0 ; i < n el em ; i ++) arr [ i ] = getInt (b ); return arr ; }
© Copyright 2024