Styles architecturaux Styles distribués – Broker GLO-3001 Hiver 2010 Broker • Permet de structurer des systèmes logiciels distribués formés de • composantes réparties, indépendantes et possiblement hétérogènes • composantes qui interagissent par des invocations de services distants. • Responsable de la coordination des communications. • Il gère entre autre la transmission des requêtes, des résultats et des exceptions. 2 Broker • Problème – Les interactions entre des composantes distribuées requiert des mécanismes de communication interprocessus – La gestion des communications par les composantes amène de nombreuses dépendances et limitations au niveau du système • Protocole de communication • Paramètres statiques (localisation des composantes) – La distribution des composantes requiert des services permettant d'ajouter, de retirer, d'échanger, d'activer et de localiser les composantes – Les applications qui utilisent les services des composantes distribuées ne doivent pas dépendre des détails spécifiques du système afin de garantir l'interopérabilité – Le fait que les composantes soient distribuées devrait être transparent aux développeurs 3 Broker • Forces à équilibrer – Les composantes du système devraient être en mesure d'accéder aux services fournis par d'autres composantes distantes de manière transparente – On doit pouvoir échanger, ajouter ou retirer des composantes à l'exécution – L'architecture devrait cacher les détails spécifiques du système aux clients des composantes 4 Broker 5 Broker • Solution – Introduire une composante intermédiaire afin de découpler les clients des serveurs • Le Broker – Les serveurs s'enregistrent auprès du Broker et rendent leurs services disponibles aux clients • Interfaces de services • Découverte dynamique de services – Les clients accèdent aux services publiés par les serveurs par l'envoi de requêtes via le Broker 6 Broker • Solution – Le Broker • Est responsable des communications – La localisation du serveur approprié – La redirection des requêtes aux serveurs – La transmission des résultats et des exceptions aux clients • Il cache les détails des interactions avec les objets distants – Aux clients – Aux développeurs • Il permet de découpler les objets • Il gère les aspects dynamiques – Le remplacement des objets – La relocalisation des objets • Il permet les interactions avec des composantes hétérogènes 7 Broker 8 Broker • Structure – Serveur • Héberge des objets qui exposent leurs fonctionnalités à travers des interfaces – Langage de définition d'interface (IDL) – Standard binaire – Client • Application qui accède aux services d’au moins un serveur • Pour faire appel à des services distants, le client envoi des requêtes au Broker – Les réponses et les exceptions sont gérées par le Broker • Les clients peuvent agir comme des serveurs, et vice-versa • Les clients n'ont pas besoin de connaître la localisation des serveurs qui hébergent les objets accédés – Il est possible d'ajouter de nouveaux services, de remplacer les services existants ou de relocaliser un service de manière transparente, et ce même à l'exécution 9 Broker – Broker • Responsable des transmissions – Des requêtes des clients vers les serveurs – Des réponses ou des exceptions des serveurs vers les clients • Est en mesure de localiser le destinataire d'une requête en se basant sur un identifiant unique • Offre un API permettant d'enregistrer les serveurs et d'invoquer les services d'un serveur • Est capable d’interopérer avec d’autres Brokers • Peut offrir des services supplémentaires – Service de nommage – Service de sérialisation 10 Broker – Proxy client (Stub) • Couche entre le client et le Broker • Permet de faire apparaître au client les objets distants comme des objets locaux • Permet de cacher des détails d'implantation – Le mécanisme de communication interprocessus utilisé pour transférer les messages – La création et la suppression d'espaces mémoire – La sérialisation des paramètres et des résultats • Encode les appels de services et décode les réponses – Proxy serveur (Skeleton) • Couche qui joue un rôle analogue à celui du proxy client • Responsable de recevoir les requêtes, de décoder les messages, puis d'appeler les services appropriés • Décode les appels de services et encode les réponses 11 Broker – Bridge • Composante optionnelle • Permet de cacher les détails d'implantation lorsque deux Brokers interagissent ensemble • Couche qui encapsule les communications entre des Brokers hétérogènes – Même principe que les proxy 12 Broker • Initialisation du serveur – Enregistrement du serveur auprès du Broker 13 Broker • Requête client Serveur 14 Broker • Interopérabilité des Brokers 15 Broker • Implantation – Java RMI – RMI (Remote Method Invocation) est un mécanisme simple qui permet de faire appel à des services sur des objets Java distants – RMI fournit des mécanismes fondamentaux • La localisation des objets distants – Un registre (RMI Registry) permet d'accéder aux objets distants • La communication avec les objets distants – Les détails des communications sont cachés par des proxy générés par RMI • Le chargement des définitions de classes pour les objets passés – Pour plus de détails sur RMI • Sun Developer Network - Remote Method Invocation – http://java.sun.com/javase/technologies/core/basic/rmi/index.jsp 16 Broker 17 Broker – Les services distants sont définis à l'aide d'interfaces Java • Ces interfaces héritent de l'interface java.rmi.Remote • Les méthodes doivent gérer les exceptions java.rmi.RemoteException • Ces interfaces sont utilisées par le client et le serveur – Les services distants sont implantés par des classes concrètes • Ces classes héritent de la classe abstraite java.rmi.UnicastRemoteObject • En cas d'erreurs, la classe génère des exceptions du type java.rmi.RemoteException • Ces classes sont utilisées par le serveur 18 Broker – Le serveur • Enregistre des objets auprès du registre d’objets (rmiregistry) – • Les clients peuvent accéder à ces objets Utilise un proxy (skeleton) pour décoder les requêtes et encoder les réponses – L’applications cliente • • • Accède aux objets distants Effectue des appels sur le proxy local qui implante la même interface que l’objet distant Utilise un proxy (stub) pour encoder les requêtes et décoder les réponses – Les proxy sont générés automatiquement • • RMIC (Java 1.4-) Compilateur Java (Java 1.5+) 19 Broker • Implantation – CORBA – CORBA (Common Object Request Broker Architecture) est une architecture distribuée dont la spécification standardisée est gérée par l'OMG (Object Management Group) – CORBA est une spécification qui permet la mise en place de systèmes distribués et qui se base sur le patron Broker • La mise en place de standards publiques permet de palier à de nombreux problèmes d'interopérabilité des systèmes – De nombreuses implantations de CORBA existent dans l'industrie et chacune apporte des caractéristiques particulières ainsi que des extensions qui leurs sont propres – La spécification de CORBA • http://www.omg.org/ 20 Broker 21 Broker – CORBA permet de spécifier les composantes sous la forme d'interfaces spécifiées dans le langage IDL • Une correspondance existe entre le langage IDL et les différents langages de programmation supportés – Des compilateurs spéciaux • Permettent de générer automatiquement le squelette des composantes distribuées • Permettent de générer les proxy clients et serveurs – Les proxy permettent les appels de services distants – CORBA permet également la découverte et l'appel dynamique des services 22 Broker – Un Broker, appelé ORB (Object Request Broker) • • Est responsable des détails des communications entre le client et les objets distants Est responsable de la gestion des références sur les objets distants – Des proxy, au niveau client et serveur, font le pont entre les clients, le ORB et les objets distants hébergés sur les serveurs – CORBA spécifie un ensemble important de services qui sont offerts par le ORB • • • • • • Services de nommage Services de transaction Services de sécurité Services de concurrence Services de notification Etc. 23 Broker – Le serveur • Les requêtes reçues par le ORB sont acheminées au bon objet par l'Object Adapter – Cette composante intermédiaire permet de spécifier des politiques pour l'activation et la persistance des objets distants • Le proxy serveur (skeleton) s'occupe de décoder les requêtes, d'encoder les réponses et de communiquer avec le ORB – L’applications cliente • Accède aux objets distants • Effectue des appels sur le proxy local qui implante la même interface que l’objet distant • Le proxy client (stub) s’occupe d’encoder les requêtes, de décoder les réponses et de communiquer avec le ORB 24 Broker • Avantages – Permet de cacher les détails des communications entre les composantes – Permet de faire appel aux services distants sans tenir compte de la localisation – Permet de cacher l'hétérogénéité des systèmes qui interagissent • Seul le Broker est dépendant de la plate-forme – Permet l'interopérabilité des différentes implantations de Brokers par le biais des Bridges – Permet la réutilisation des services distants – La modification des comportements internes du serveur n'affecte pas les clients tant que les interfaces restent stables – Facilite les tests sur les composantes individuelles 25 Broker • Inconvénients – Efficacité restreinte • Distribution des composantes • Opérations de gestion des serveurs et des clients • Opérations d'encodage et de décodage des requêtes – Tolérance aux fautes faible • Si on a qu'un seul serveur implantant un service et qu’il tombe en panne, toutes les applications utilisant ce service sont affectées – Il est difficile de tester le système distribué en entier 26 Broker - Exemple • Calculateur distant – Permet de faire des opération de base (+, -, *, /) – Le calculateur est un objet distant hébergé sur un serveur – Exécution de l’exemple • run-all.bat set CLASSPATH=.\build\classes\ start rmiregistry start java -Djava.security.policy=policy.all Server start java -Djava.security.policy=policy.all Client – Politiques de sécurité pour des fins de test • policy.all grant { permission java.security.AllPermission; }; 27 Broker - Exemple /** * Interface des services distants */ public interface ICalculator extends public double add(double a, double public double sub(double a, double public double mul(double a, double public double div(double a, double } Remote { b) throws b) throws b) throws b) throws RemoteException; RemoteException; RemoteException; RemoteException; 28 Broker - Exemple /** * Implantation du calculateur (Objet distant) */ public class CalculatorImpl extends UnicastRemoteObject implements ICalculator { public CalculatorImpl() throws RemoteException { super(); } public double add(double a, double b) throws RemoteException { return a + b; } public double sub(double a, double b) throws RemoteException { return a - b; } public double mul(double a, double b) throws RemoteException { return a * b; } public double div(double a, double b) throws RemoteException { return a / b; } } 29 Broker - Exemple /** * Serveur */ public class Server { public static void main(String[] args) { try { // Security manager System.setSecurityManager(new RMISecurityManager()); // Register ICalculator calc = new CalculatorImpl(); Naming.rebind("CalculatorService", calc); System.out.println("Waiting for requests ..."); } catch (java.net.MalformedURLException ex) { System.out.println("Malformed URL: " + ex.toString()); } catch (RemoteException ex) { System.out.println("Remote exception: " + ex.toString()); } } } 30 Broker - Exemple /** * Client */ public class Client { public static void main(String[] args) { try { // Security manager System.setSecurityManager(new RMISecurityManager()); // Get a reference on the remote object String url = "//localhost/CalculatorService"; ICalculator remoteCalc = (ICalculator)Naming.lookup(url); System.out.println("2.0 + System.out.println("9.0 System.out.println("2.5 * System.out.println("121.0 5.0 = " + remoteCalc.add(2.0, 5.0)); 3.0 = " + remoteCalc.sub(9.0, 3.0)); 4.0 = " + remoteCalc.mul(2.5, 4.0)); / 11.0 = " + remoteCalc.div(121.0, 11.0)); } catch (RemoteException ex) { System.out.println("Error in lookup: " + ex.toString()); } catch (java.net.MalformedURLException ex) { System.out.println("Malformed URL: " + ex.toString()); } catch (java.rmi.NotBoundException ex) { System.out.println("NotBound: " + ex.toString()); } } } 31