Programmation par RPC et Java
Transcription
Programmation par RPC et Java
2A-SI 3 – Prog. réseau et systèmes distribués 3.2 – Programmation par RPC et JavaRMI Stéphane Vialle [email protected] http://www.metz.supelec.fr/~vialle Support de cours élaboré avec l’aide de l’équipe pédagogique du cours de SI Programmation par RPC et Java-RMI : - Principes des RPC - Utilisation d’un IDL - Principes des Java-RMI - Mode opératoire des Java-RMI - Hiérarchie de classes Java - Exemple de client-serveur en Java-RMI - Limitations du déploiement 1 Programmation par RPC et Java-RMI Principes des RPC RPC = « Remote Procedure Call » Objectif : appels locaux et distants avec la même syntaxe • 1ère version : Birrel & Nelson en 1984 – L’utilisateur écrit toute l’application : le client, le serveur et les mécanismes d’envoi et de réception de messages !! – Concepts simples, mais complexes à mettre en œuvre Peu utilisé • SUN RPC en 1988 – Plus simple, – Utilise « rpcgen » : génère une partie des fichiers de RPC – Utilise le DNS (localisation du serveur : adresse IP) + Portmap (localisation du service : # port) Programmation par RPC et Java-RMI Principes des RPC Service RPC (talon) Protocole de Service RPC (talon) Protocole de communication communication 1 Appelé 2 appel Réseau Appel 5 retour Client (appelant) 4 3 retour Serveur (appelé) 2 Programmation par RPC et Java-RMI Principes des RPC Talon client : stub • C’est la procédure d’interface du site client qui reçoit l’appel en mode local le transforme en appel distant en envoyant un message reçoit les résultats après l'exécution retourne les paramètres résultats comme dans un retour de procédure Talon serveur : skeleton • C’est la procédure sur le site serveur qui reçoit l’appel sous forme de message fait réaliser l’exécution sur le site serveur par la procédure serveur (choix de la procédure) retransmet les résultats par message Programmation par RPC et Java-RMI : - Principes des RPC - Utilisation d’un IDL - Principes des Java-RMI - Mode opératoire des Java-RMI - Hiérarchie de classes Java - Exemple de client-serveur en Java-RMI - Limitations du déploiement 3 Programmation par RPC et Java-RMI Utilisation d’un IDL • Un langage pour la spécification des interfaces entre les clients et les serveurs : – Spécification commune au client et au serveur • Le « contrat » entre le client et le serveur – Définition des types et natures des paramètres • IN, OUT, IN-OUT, par valeur, par référence – Définition indépendante de la plate-forme • Indépendante du langage, de l’OS et de la machine • Utilisation de ces définitions pour générer automatiquement : – Le talon client (ou proxy, ou stub) – Le talon serveur (ou squelette, ou skeleton) • « projection » dans un langage de programmation Programmation par RPC et Java-RMI Utilisation d’un IDL Interface écrite en « IDL » Client Compilateur IDL Talon coté client (Stub) Protocole de communication Serveur Talon coté Serveur (Skeleton) Réseau Protocole de communication 4 Programmation par RPC et Java-RMI : - Principes des RPC - Utilisation d’un IDL - Principes des Java-RMI - Mode opératoire des Java-RMI - Hiérarchie de classes Java - Exemple de client-serveur en Java-RMI - Limitations du déploiement Programmation par RPC et Java-RMI Principes des Java-RMI • Un RPC objet intégré à Java • Interaction d'objets situés dans des espaces d'adressage différents sur des machines distinctes • Simple à mettre en œuvre : un objet distribué se manipule comme tout autre objet Java • Différences RPC/RMI : – Il existe un module de localisation sur le host-serveur distant (la rmiregistry) : localisation de chaque objet-serveur. – Les RMI sont plus vulnérables aux pannes: impossible de distinguer le cas de panne du serveur d’un problème réseau (moins de détails dans les CR d’erreurs). • Les interfaces (contrats) sont des interfaces Java → L’IDL est Java lui-même 5 Programmation par RPC et Java-RMI Principes des Java-RMI objet client objet serveur état référence méthode_1() appel Talon client Talon serveur Système de communication Référence d'objet + méthode + arguments Résultat ou exception méthode_n() • désignation • envoi de requêtes • exécution de requête • retour de résultat Programmation par RPC et Java-RMI : - Principes des RPC - Utilisation d’un IDL - Principes des Java-RMI - Mode opératoire des Java-RMI - Hiérarchie de classes Java - Exemple de client-serveur en Java-RMI - Limitations du déploiement 6 Programmation par RPC et Java-RMI Mode opératoire des Java-RMI 0 - A la création de l’objet-serveur, un stub et un skeleton (avec un port de communication) sont créés sur le host-serveur 1 - L'objet-serveur s'enregistre auprès du Naming de sa JVM (méthode rebind) 2 - Le Naming enregistre le stub de l’objet (sérialisé) auprès du serveur de noms (rmiregistry) 3 - Le serveur de noms est prêt à fournir des références sur l’objet-serveur rmiregistry stub Client Naming Serveur stub Skeleton JVM Client JVM Serveur Programmation par RPC et Java-RMI Mode opératoire des Java-RMI 4 - L'objet client fait appel à son Naming pour localiser l'objet-serveur sur l’host-serveur (méthode lookup) 5 - Le Naming récupère le stub vers l'objet-serveur auprès de la rmiregistry 6 – Le naming installe l’objet Stub sur le poste client et retourne sa référence au client 7 - Le client effectue l'appel à l’objet serveur par appel à l’objet local Stub rmiregistry Naming stub Client Naming Serveur Stub JVM Client Skeleton JVM Serveur 7 Programmation par RPC et Java-RMI Mode opératoire des Java-RMI Etapes du développement et déploiement : 1. Codage – description de l’interface du service – écriture du code du serveur qui implante l’interface – écriture du client qui appelle le serveur 2. Compilation – compilation des sources serveurs (javac) – génération des stub et skeleton (rmic) – compilation des sources client (javac) 3. Activation – lancement du serveur de noms (rmiregistry) – lancement du serveur – lancement du client Programmation par RPC et Java-RMI Mode opératoire des Java-RMI Etapes du développement et déploiement : 1 – programmation: Interface java Server. Client. java java 2.1 - javac Server.java Server.class 2.2 - rmic Server Server_Stub.class Server_Skel.class 2.3 - javac Client.java 3.1 – rmiregistry 3.2 – java Server Client.class 3.3 – java Client 8 Programmation par RPC et Java-RMI : - Principes des RPC - Utilisation d’un IDL - Principes des Java-RMI - Mode opératoire des Java-RMI - Hiérarchie de classes Java - Exemple de client-serveur en Java-RMI - Limitations du déploiement Programmation par RPC et Java-RMI Hiérarchie de classes Java Interface : RemoteObject Interface : RemoteServer Interface : Classe : Activatable UnicastRemoteObject Serveurs Interface : RemoteStubs Interface : ActivationGroup_Stub Stubs/Skeletons 9 Programmation par RPC et Java-RMI Hiérarchie de classes Java Interface : RemoteObject Interface : RemoteServer Interface : Activatable Interface : RemoteStubs Classe : UnicastRemoteObject • Serveurs démarrés explicitement • Objet/Service ayant la durée de vie du processus serveur • Pour des comm. P2P entre processus actifs Interface : ActivationGroup_Stub • Utilise des comm. TCP Public class MyServerRmi extends UnicastRemoteObject Implements MyInterfaceRmi { … } Programmation par RPC et Java-RMI Hiérarchie de classes Java Interface : RemoteObject Interface : RemoteServer Interface : Activatable Interface : RemoteStubs Classe : UnicastRemoteObject • Serveurs démarrables par le système • Objet/Service persistant (non liés à la durée de vie d’un processus) Interface : ActivationGroup_Stub • Les constructeurs proposent de définir un port sur lequel sera exporté le service. Sinon un port quelconque sera choisi. 10 Programmation par RPC et Java-RMI Hiérarchie de classes Java Interface : RemoteObject Interface : RemoteServer Interface : Activatable Classe : UnicastRemoteObject Interface : RemoteStubs Interface : ActivationGroup_Stub • Interfaces à destination des classes « stubs » et « skeletons » (les tallons client et serveur générés par rmic) • Gérées par le mécanisme des Java-RMI Programmation par RPC et Java-RMI : - Principes des RPC - Utilisation d’un IDL - Principes des Java-RMI - Mode opératoire des Java-RMI - Hiérarchie de classes Java - Exemple de client-serveur en Java-RMI - Limitations du déploiement 11 Programmation par RPC et Java-RMI Ex. client–serveur en Java-RMI Règles d’écriture des RMI : • Les objets locaux passés en paramètres doivent être (juste) « serializable » – Dans la majorité des cas il suffit d’ajouter : « extends Serializable » dans l’interface de leur classe « implements Serializable » dans la définition de leur classe – Rien à faire pour les objets de base (int, double, …) – Les objets difficiles à « serialiser » sont les threads … éviter de passer des threads en paramètres d’appel RMI ! Programmation par RPC et Java-RMI Ex. client–serveur en Java-RMI Règles d’écriture des RMI : • Les objets distants ont plus de contraintes : – L’interface distante doit être publique – L’interface distante doit étendre l’interface java.rmi.Remote – La classe distante hérite (généralement) de java.rmi.server.UnicastRemoteObject … … qui implémente java.rmi.Remote (parfait!) – Chaque méthode distante doit déclarer au moins l’exception java.rmi.RemoteException • Les objets distants doivent être déclarés par une référence sur leur interface (uniquement). 12 Programmation par RPC et Java-RMI Ex. client–serveur en Java-RMI rmiregistry Client Java Serveur Java « TheServer » Cas simple : • Le client connaît le nom du serveur (« TheServer ») • La rmiregistry est lancée sur le serveur • Le client passe des arguments « de base » (int) // l'interface à exporter (deux services définis) public interface CalculRmi extends java.rmi.Remote { public int plus(int un, int deux) throws java.rmi.RemoteException; } public int mult(int un, int deux) throws java.rmi.RemoteException; Programmation par RPC et Java-RMI Ex. client–serveur en Java-RMI // Client utilisant des services d’un objet-serveur distant import java.rmi.*; public class ClientRmi { static public void main(String arg[]) { int i1, i2, res; String NomHostServeur, NomObjServeur; CalculRmi ObjServeur; // Parse la ligne de commande NomHostServeur = arg[0]; NomObjServeur = arg[1]; i1 = Integer.parseInt(arg[2]); i2 = Integer.parseInt(arg[3]); try { // Recherche de l’objet-serveur distant dans la rmiregistry ObjServeur = (CalculRmi) Naming.lookup( "rmi://" + NomHostServeur + "/" + NomObjServeur); // Usage du service distant trouvé res = ObjServeur.plus(i1, i2); } catch (Exception e){ System.out.println("Erreur RMI " + e.getMessage()); System.exit(1); } } } System.out.println("Résultat appel RMI: " + res); 13 Programmation par RPC et Java-RMI Ex. client–serveur en Java-RMI // Objet-Serveur RMI (debut) import java.util.*; import java.rmi.*; import java.rmi.server.*; public class ObjServeurRmi extends UnicastRemoteObject implements CalculRmi { private String nomObjServeur; public ObjServeurRmi(String s) throws RemoteException { super(); nomObjServeur = s; } public String getNomObjServeur() { return nomObjServeur; } // Premier service exporté public int plus(int a, int b)throws RemoteException { return a + b; } // Deuxième service exporté public int mult(int a, int b)throws RemoteException return a * b; } Programmation par RPC et Java-RMI Ex. client–serveur en Java-RMI // Objet-Serveur RMI (fin) // Fonction main : pour le lancement du serveur static public void main(String arg[]) { System.setSecurityManager(new RMISecurityManager()); try { ServeurRmi srmi = new ObjServeurRmi("Calculateur"); Naming.rebind("//localhost/Calculateur", srmi); System.out.println("Enregistrement objet-serv OK"); } } } catch (Exception e) { System.out.println("Pb enregistrement service: " + e.getMessage()); System.exit(1); } 14 Programmation par RPC et Java-RMI : - Principes des RPC - Utilisation d’un IDL - Principes des Java-RMI - Mode opératoire des Java-RMI - Hiérarchie de classes Java - Exemple de client-serveur en Java-RMI - Limitations du déploiement Programmation par RPC et Java-RMI Limitations du déploiement (1) Déploiement simple entre deux machines distantes : Skeleton ServerA ObjServeurA Client Veut appeler l’objet serveur « K » … où est-il ? Skeleton ServerB ObjServeurB Skeleton ServerC ObjServeurC rmiregistry Skeleton ServerD ObjServeurD Skeleton ServerE ObjServeurE Skeleton ServerF ObjServeurF rmiregistry Quand le système grossit il est difficile de savoir à quelle rmiregistry s’adresser ! Un annuaire global des services devient nécessaire ! 15 Programmation par RPC et Java-RMI Limitations du déploiement (2a) Déploiement simple entre deux machines distantes : Client Stub Server ObjLoc … Res = Server.service(ObjLoc) … Objets locaux : - passés par valeurs - doivent être serializable ObjLoc-copie par valeur Skeleton Server ObjServeur rmiregistry serveur Appel d’objets distants : - appelés par « références sur leurs stubs » Programmation par RPC et Java-RMI Limitations du déploiement (2b) Déploiement complexe entre N machines : ➔ invocation dynamique de classe Client Stub ObjDist Skeleton ObjDist ObjDist Stub Server ObjLoc … Res = Server.service(ObjLoc, « IdObjAndClassDistants ») … Invoc. Dyna Passage d’objets locaux : - passés par valeurs - doivent être serializable Stub ObjDist ObjLoc-copie par valeur Skeleton Server ObjServeur rmiregistry serveur Passage d’objets distants : - Nécessitent l’invocation dynamique de classes … 16