Introduction aux applications réparties Noël De Palma Projet SARDES INRIA Rhône-Alpes http://sardes.inrialpes.fr/~depalma Noel.depalma@inrialpes.fr ...
Applications réparties Def : Application s’exécutant sur plusieurs sites reliés par un réseau de communication Intérêt des applications réparties Caractéristiques et besoins Outils de bases Modèles d’applications réparties
Intérêt des applications réparties Besoin de communication et de partage d’information Besoin de tolérance aux fautes Besoin de puissance de calcul
Web Accès universel à de l’information Get/post Client Http Serveur Http html
Qq problèmes de base en distribué Hétérogénéité ? Passage à grande échelle ? Tolérance aux pannes ? Sécurité ? Plus difficiles à concevoir, à programmer, à déployer et à administrer Besoin de modèles & d’outils adaptés
Outils de programmation Outils de base : socket Middleware (Intergiciel) Couche logiciel (répartie) destinée à : Masquer la répartition des traitements et des données Masquer l ’hétérogénéité des machines & des systèmes Fournir des services associés pour gérer : Fiabilité Sécurité Scalabilité … Applications “Middleware” Site 1 Site 2 Interface Système de communication Services de gestion de la distribution
Catégorie d’intergiciel Différents types d ’intergiciels pour adresser différents problèmes Analyse du problème => choix de l’ intergiciel Différents Modèle d’exécution Modèle client serveur Modèle de communication par message
Modèle de communication par messages Message Passing (communication par messages) Message Queuing (communication par file de message) Publish/Subscribe (communication par abonnements)
Message passing Principes directeurs communication asynchrone communication directe ou indirecte (via des “portes”) problème de désignation, localisation des entités coopérantes messages éventuellement typés producteur consomateur (nom_de_service, paramètres, port_C) exécution du service Port_C Port_S
Message Queuing Queue de messages persistantes asynchronisme et fiabilité Indépendance de l'émetteur et du destinataire Le destinataire n’est pas forcément actif send recv Client Serveur
Publish/Subscribe (1) Désignation anonyme Communication 1-N L’émetteur envoie un message Basé sur un sujet (subject-based) Basé sur un contenu (content-based) Le récepteur s’abonne (à un sujet ou un contenu) Communication 1-N Plusieurs récepteurs peuvent s’abonner
Publish/Subscribe (2) consommateur producteur subscribe publish recv
Modèle client-serveur définition Application client/serveur Appel synchrone d’un service au travers d’un échange de messages (requête/réponse) plutôt que par un partage de données (mémoire ou fichiers) serveur programme offrant un service sur un réseau (par extension, machine offrant un service) client programme qui émet des requêtes (ou demandes de service). Il est toujours l’initiateur du dialogue
Modèle client-serveur Deux messages (au moins) échangés Le premier message correspondant à la requête est celui de l'appel de procédure, porteur des paramètres d'appel. Le second message correspondant à la réponse est celui du retour de procédure porteur des paramètres résultats. appel n_proc (p_in, p_out) client Procédure n_proc (p_in, p_out) begin end serveur Appel(p_in) Retour(p_out)
Client/Serveur en mode connecté Si le connect() du client arrive entre le listen() et l’accept(), la connexion est mise en attente jusqu’à ce qu’elle soit acceptée. C ’est le schéma classique d’un client/serveur qui utilise TCP. La fiabilité est assurée par TCP mais il ne garantit pas la frontière des messages. C’est-à-dire que si l’on envoie un message de 10 Ko suivi d ’un autre de 5 Ko, il se peut que le read() lise les 15 Ko d’un seul coup. On a donc intérêt de savoir à l’avance la taille du message à lire.
Client/Serveur en mode non connecté C ’est le schéma classique lorsque l ’on veut réaliser une application client/serveur en utilisant UDP. Attention, UDP n’est pas fiable et c’est au programmeur de l’application de gérer la perte, la duplication, la détérioration ou le déséquencement des paquets ! Sous Windows, il est possible d ’utiliser des sockets non bloquantes ou asynchrones. Dans ce cas, il est nécessaire de se synchroniser. Dans le schéma ci-dessus, si le serveur utilise des sockets non bloquantes, il faut trouver un moyen pour que le serveur attende l’arrivée de la requête avant d’envoyer la réponse. Sous Unix, nous n’utiliserons que des sockets bloquantes.
Un exemple TCP + serialisation Passage d’objets par valeur à l’aide de la serialization L’objet à passer à passer au serveur : public class voiture implements Serializable{ public String type; public int imm; public voiture(String type, int imm) { this.type = type; this.imm = imm; } public String toString() { return this.type+" "+this.imm;
Un exemple :TCP + serialisation public class client { public static void main (String[] str) { try { voiture v0 = new voiture("peugeot",171838); Socket CNX = new Socket("electron.inria.fr",6666); ObjectOutputStream po = new ObjectOutputStream (CNX.getOutputStream()); ObjectInputStream pi = new ObjectInputStream (CNX.getInputStream()); po.writeObject(v0); voiture v1 = (voiture) pi.readObject(); CNX.close(); System.out.println(’’v0 :’’+v0 ); System.out.println(’’v1 :’’+v1 ); } catch (Exception e) { System.out.println("An error has occurred ...");
Un exemple : TCP + serialisation Le serveur public static void main (String[] str) { ServerSocket ss; int port = 6666; ss= new ServerSocket(port); System.out.println("Server ready ..."); while (true) { slave rh = new slave(ss.accept()); rh.start(); }
Un exemple TCP + serialisation public class slave extends Thread { Socket currentRq; public slave(Socket currRq) { this.currentRq = currRq; } public void run() { ObjectInputStream pi = new ObjectInputStream(currentRq.getInputStream()); ObjectOuputStream po = new ObjectOutputStream(currentRq.getOuputStream()); voiture v = (voiture)pi.readObject(); System.out.println("voiture recu : "+ v); v.imm = 381817; po.writeObject(v); currentRq.close();
Appel de procédure à distance (RPC) Outils de base pour réaliser le mode client-serveur. L'opération à réaliser est présentée sous la forme d'une procédure que le client peut faire exécuter à distance par un autre site : le serveur. Forme et effet identique à ceux d'un appel local Simplicité (en l'absence de pannes) Sémantique identique à celle de l'appel local
RPC [Birrel & Nelson 84] Principe de réalisation client réseau serveur Appelant Appel Service RPC (talon) return Protocole de communication Protocole de communication Service RPC (talon) appel Appelé return A B C E D
Evolution des architectures client/serveur : application 3-tiers Présentation/logique applicative/données Implantation ad-hoc HTTP Serveur Web JDBC Client Web Servlet SGBD J2EE HTTP Client Web Serveur Web Servlet EJB SGBD
RPC 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
Appel de méthode à distance Remote Method Invocation (RMI) objet client objet serveur état référence Methode_1 Talon client Talon serveur appel Methode_n Système de communication désignation envoi de requêtes exécution de requête retour de résultat Référence d'objet + méthode + arguments Résultat ou exception
Remote Reference Layer Java RMI Architecture JVM JVM Objet Client Objet Serveur Proxy Skeleton Remote Reference Layer Transport
Java RMI Architecture Œ rmiregistry stub Naming Client Serveur Skeleton JVM Client JVM Serveur
Java RMI Mode opératoire coté serveur 0 - A la création de l ’objet, un stub et un skeleton (avec un port de communication) sont créés coté 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 à donner des références à l’objet serveur
Java RMI Architecture ‘ ’ ’ ’ rmiregistry Naming stub Naming Client ‘ Serveur ’ ’ Stub ’ Skeleton JVM Client JVM Serveur
Java RMI Mode opératoire coté client 4 - L'objet client fait appel au Naming pour localiser l'objet serveur (méthode lookup) 5 - Le Naming récupère le stub vers l'objet serveur, ... 6 - installe l’objet Stub et retourne sa référence au client 7 - Le client effectue l'appel à l’objet serveur par appel à l’objet Stub
Java RMI Manuel d'utilisation Définition de l'interface de l'objet réparti interface : "extends java.rmi.Remote" methodes : "throws java.rmi.RemoteException" paramètres sérializable : "implements Serializable" paramètres référence : "implements Remote" Ecrire une implémentation de l'objet serveur classe : "extends java.rmi.server.UnicastRemoteObject"
Java RMI Mode opératoire codage description de l’interface du service écriture du code du serveur qui implante l’interface écriture du client qui appelle le serveur compilation compilation des sources (javac) génération des stub et skeleton (rmic) activation lancement du serveur de noms (rmiregistry) lancement du serveur lancement du client
RPC Java RMI : écriture de l’interface Mêmes principes de base que pour l’interface d’un objet local Principales différences l’interface distante doit être publique l’interface distante doit étendre l’interface java.rmi.Remote chaque méthode doit déclarer au moins l’exception java.rmi.RemoteException toute référence d ’objet (objet "remote" ou "sérialisable") doit être déclaré comme une interface
Java RMI Exemple : Interface fichier Hello_itf.java public interface Hello_itf extends java.rmi.Remote { String sayHello() throws java.rmi.RemoteException; } Description de l’interface
Java RMI : écriture du serveur Serveur = la classe qui implémente l’interface spécifier les interfaces distantes qui doivent être implémentées objets passés par copie (il doivent implémenter l’interface java.io.serialisable) objets passés par référence (en fait une référence à un stub) c’est un objet java standard définir le constructeur de l’objet fournir la mise en œuvre des méthodes pouvant être appelée à distance ainsi que celle des méthodes n’apparaissant dans aucune interface implémentée créer au moins une instance du serveur enregistrer au moins une instance dans le serveur de nom (rmiregistry)
Java RMI Exemple : Serveur fichier HelloServeur.java import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class HelloServeur extends UnicastRemoteObject implements Hello_itf { private String msg; // Constructeur public HelloServeur(String msg) throws java.rmi.RemoteException { this.msg = msg; } // Implémentation de la méthode distante. public String sayHello() throws java.rmi.RemoteException { return "Hello world: " + msg; … Réalisation du serveur
Java RMI Exemple : Serveur fichier HelloServeur.java … public static void main(String args[]) { try { // Crée une instance de l ’objet serveur. Hello_itf obj = new HelloServeur("Coucou"); // Enregistre l'objet créer auprès du serveur de noms. Naming.rebind("//suldrun/mon_serveur", obj); System.out.println("HelloServeur " + " bound in registry"); } catch (Exception exc) {… } } Réalisation du serveur (suite) ATTENTION : dans cet exemple le serveur de nom doit être activé avant la création du serveur
Java RMI Activation du serveur de nom par le serveur fichier HelloServeur.java public static void main(String args[]) { int port; String URL; try { // transformation d ’une chaîne de caractères en entier Integer I = new Integer(args[0]); port = I.intValue(); } catch (Exception ex) { System.out.println(" Please enter: Server <port>"); return; } try { // Création du serveur de nom - rmiregistry Registry registry = LocateRegistry.createRegistry(port); // Création d ’une instance de l’objet serveur Hello_itf obj = new HelloServeur("Coucou"); // Calcul de l’URL du serveur URL = "//"+InetAddress.getLocalHost().getHostName()+":"+port+"/mon_serveur"; Naming.rebind(URL, obj); } catch (Exception exc) { ...
Java RMI Compilation Compilation de l’interface, du serveur et du client javac Hello_itf.java HelloServeur.java HelloClient.java Génération des talons rmic HelloServeur skeleton dans HelloServeur_Skel.class stub dans HelloServeur_Stub.class.
Java RMI Déploiement 1) Activation du serveur de nom start rmiregistry (W95) ou rmiregistry & (Unix) 2) Activation du serveur java HelloServeur java -Djava.rmi.server.codebase=http://suldrun/… path indiquant à quelle endroit la machine virtuelle cliente va pouvoir chercher le code du stub Nécessaire si le client et le serveur ne sont pas sur la même station 3) Activation du client java HelloClient
Java RMI Principe de l’appel de procédure Java VM Java VM Client R_objet1.m () R_objet1 m () Skeleton R_objet1 Stub R_objet1
Java RMI Passage en paramètre d’un objet sérialisable Java VM Java VM O2 Objet objet1 m ( O2 ) Client R_objet1.m ( O2 ) clone_O2 Stub R_objet1 Skeleton R_objet1
Java RMI Passage en paramètre d’un objet remote Objet O2 Java RMI Passage en paramètre d’un objet remote Java VM Java VM Stub R_O2 Objet objet1 m ( R objet ) Client R_objet1.m ( R O2 ) Stub R_objet1 Skeleton R_objet1
Java RMI Passage en paramètre d’un objet remote Objet O2 Java RMI Passage en paramètre d’un objet remote Java VM Java VM Stub R_O2 Objet objet1 m ( R objet ) Client R_objet1.m ( R O2 ) Stub R_O2 Stub R_objet1 Skeleton R_objet1
Chargement dynamique et sécurité Si le code du stub n’est pas présent sur le site local, le protocole RMI prévoit le chargement dynamique du stub en utilisant un serveur web et le protocole HTTP java -Djava.rmi.server.codebase=http://suldrun/… Si chargement dynamique… RMI impose l’utilisation d’un gestionnaire de sécurité (SecurityManager) interdit l’accès à des ressources protégées depuis du code téléchargé créer et installer le "gestionnaire de sécurité" System.setSecurityManager(new RMISecurityManager());
Java RMI : bilan Très bon exemple de RPC Des ouvertures facilité d’utilisation intégration au langage Java et à l’internet utilisation de l’apport de Java Hétérogénïté des plateformes -> machine virtuelle Passage de référence -> sérialisation ou référence à distance Persistance -> sérialisation Absence de talon -> chargement dynamique Désignation -> URL Des ouvertures Serveurs multiplexés ? Appels asynchrones ? Utilisation d’autres protocoles réseaux ?