Introduction aux applications réparties Noël De Palma Projet SARDES INRIA Rhône-Alpes depalma...

Preview:

Citation preview

Introduction aux applications réparties

Noël De Palma

Projet SARDES

INRIA Rhône-Alpeshttp://sardes.inrialpes.fr/~depalma

Noel.depalma@inrialpes.fr

Applications réparties

• Intérêt des applications réparties• Caractéristiques et besoins• Outils de bases• Modèles d’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

• 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

Client Http Serveur Http

Get/post

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 decommunication

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

exécution

du

service

Port_SPort_C

(nom_de_service, paramètres, port_C)

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– 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

publish

producteur

subscribe

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

Retour(p_out)

Appel(p_in)

Client/Serveur en mode connecté

établissement de la connexion

bloqué jusqu'à la réception de la réponse

bloqué jusqu'à la réception de la requête

envoi requête

Client Serveur

socket()

connect()

write()

read()

close()

socket()

bind()

write()

read()

close()

Création de la socket

traitement de la requête

envoi réponse

traitement de la réponse

Fermeture de la socket

listen()

accept()

Client/Serveur en mode non connecté

bloqué jusqu'à la réception de la réponse

bloqué jusqu'à la réception de la requête

envoi requête

Client Serveur

socket()

bind()

sendto()

recvfrom()

close()

socket()

bind()

sendto()

recvfrom()

close()

Création de la socket

Assignation n°port - @ IP

traitement de la requête

envoi réponse

traitement de la réponse

Fermeture de la socket

Un exemple TCP + serialisationPassage 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 + serialisationpublic 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 + serialisationpublic 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

client serveur

RPC [Birrel & Nelson 84] Principe de réalisation

Service RPC(talon)

appel

réseau

Appelant

Appel

Service RPC(talon)

return

Protocole decommunication

Protocole decommunication

Appelé

return

A

E

B

D

C

Evolution des architectures client/serveur : application 3-tiers

ClientWeb

ServeurWeb SGBD

HTTPServlet

ClientWeb

ServeurWeb SGBD

HTTPServlet

JDBC

EJB

• Implantation ad-hoc

• J2EE

• Présentation/logique applicative/données

Appel de méthode à distanceRemote Method Invocation (RMI)

Methode_1

Methode_n

état

objet serveurobjet client

appel

Système de communication

Talonserveur

Talonclient

référence

Référence d'objet + méthode + arguments

Résultat ou exception

désignationenvoi de requêtesexécution de requêteretour de résultat

JVMJVM

Java RMIArchitecture

Objet ClientObjet ClientObjet ClientObjet Client Objet ServeurObjet ServeurObjet ServeurObjet Serveur

ProxyProxyProxyProxy SkeletonSkeletonSkeletonSkeleton

Remote Reference LayerRemote Reference LayerRemote Reference LayerRemote Reference Layer

TransportTransportTransportTransport

Java RMIArchitecture

JVM ClientJVM Serveur

ClientClientClientClient

SkeletonSkeletonSkeletonSkeleton

rmiregistryrmiregistryrmiregistryrmiregistry

ServeurServeurServeurServeur

NamingNamingNamingNaming

Œ

Ž

stubstubstubstub

stubstubstubstub

Java RMIMode 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 RMIArchitecture

JVM ClientJVM Serveur

NamingNamingNamingNaming

ClientClientClientClient

StubStubStubStubSkeletonSkeletonSkeletonSkeleton

rmiregistryrmiregistryrmiregistryrmiregistry

ServeurServeurServeurServeur

NamingNamingNamingNaming

’ ’ ’

stubstubstubstub

Java RMIMode 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 RMIManuel 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 RMIMode 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

fichier Hello_itf.java

public interface Hello_itf extends java.rmi.Remote { String sayHello() throws java.rmi.RemoteException;}

fichier Hello_itf.java

public interface Hello_itf extends java.rmi.Remote { String sayHello() throws java.rmi.RemoteException;}

Java RMIExemple : Interface

Descriptionde

l’interface

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;}

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;}

Java RMIExemple : Serveur

Réalisationdu

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) {… }}

}

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) {… }}

}

Java RMIExemple : Serveur

Réalisationdu

serveur(suite)

ATTENTION : dans cet exemple le serveur de nomdoit être activé avant la création du 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) { ...

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 RMIActivation du serveur de nom par le serveur

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 RMIPrincipe de l’appel de procédure

Java VM Java VM

ClientR_objet1.m ()

StubR_objet1

SkeletonR_objet1

R_objet1m ()

Java RMIPassage en paramètre d’un objet sérialisable

Java VM Java VM

ClientR_objet1.m ( O2 )

StubR_objet1

SkeletonR_objet1

Objet objet1m ( O2 )

O2

clone_O2

Java RMIPassage en paramètre d’un objet remote

Java VM Java VM

ClientR_objet1.m ( R O2 )

StubR_objet1

SkeletonR_objet1

Objet objet1m ( R objet )

StubR_O2

Objet O2

Java RMIPassage en paramètre d’un objet remote

Java VM Java VM

ClientR_objet1.m ( R O2 )

StubR_objet1

SkeletonR_objet1

Objet objet1m ( R objet )

StubR_O2

Objet O2

StubR_O2

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());

Recommended