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