projet Netflix c, échange entre composants
Cet article est la suite du précédant, à lire d'abord
Comment faire discuter 2 composants à distance ?
RPC à l’ancienne en C
SOAP (Rest)
WSDL
RMI
.net remoting (anciennement DCOM) LE système Microsoft n’est basé que sur du RPC.
REST est à la mode en entreprise. Voici quelques formations ;
https://consultingit.fr/fr/formation-a-la-programmation-des-web-services
Client (rond = contrat) -> REST -> serveur
Le composant qui a une flèche orientée veut dire : pour le déployer,
->
Est obligé d’avoir ça ->
Contrat = méthodes appelées par le client (web-services)
LE client et le serveur doivent connaitre le contrat, sinon ils ne peuvent pas communiquer.
Appel Rest = nom de méthode, type de retour, exemple en springrest
Une question? Posez-la ici
Exemple l’appel REST
Entre le portail et le convertisseur
@POST ou @GET ou @CONSUMES(Json) ou @PRODUCES(XML)
Public Response Methodname startConversion (arguments String Format, String path){
…
}
Ou
Int getStatus(Short id)
Côté serveur, en mémoire, en cache, en hashmap, on a in ID
Dans la réponse du convertisseur, on renvoie l’ID au protail
Le portail sait que Games of Thrones, en Full HD, saison 6 épisode 6 est l’ID 3
Quand id =100 (pour 100%) la conversion est terminée.
Une question? Posez-la ici
Si je découple, comment faire communiquer mes 2 composants ?
Le convertisseur prend un fichier en entrée, et le convertit et l’enregistre en sortie.
Le StartConversion est uen méthode asynchrone qui lance la conversion et retourner returns immediatly ID with response
Attention plusieurs méthodes :
- StartConversion, démarre la conversion
- Conversion, effectue la conversion
- getStatus, demande où en est le pourcentage, INT
Le fichier se trouve par exemple sur un HDFS
Hdfs:///series.cachecdn.in/series … sur un autre datacenter en fibre optique, ou en local, etc. Le path doit être réfléchi en « distribué »
Le ficher est quelquepart et répliqué.
Le point de montage est le début d’une architecture distribuée.
Un scénario est modélisé en UML par un diagramme de séquence
Le métier d’« Architecte logiciel de composants distribués » répond à la question pourquoi découpler ?
Quel comportement adopter ? Synchrone ? Asynchrone ?
Définir le contrat : implémenter dans le serveur des méthodes qui vont être appelées par le client.
Quand on nous demande un diagramme de composants, expliquer les mécanismes, et pourquoi on a choisit ceux là.
Spring-rest 4.7 est une librairie pour faire du REST coté serveur.
Je découple la partie service de la partie conversion
Nouveau composant :
<jar> async-conversion-mngmt
Découplage : donner à chaque partie logicielle un composant
Nouvelle méthode asynch.launch.converter
Avantage du découplage : si je veux remplacer le REST par du SOAP, je peux.
Rendre son code réutilisable et indépendant.
Il faut contacter un développeur specialiste du REST, parfait je connais NicolasD
WilliamT spécialisé en vidéo va lancer le wraper video
Découplage en agile : j’ai une story pour chaque membre de mon groupe
L’Architecte découple les applications en composants pour répartir les traitements.
Se j’appelle 20 fois StartConversion, je vais avoir 20 conversions en même temps.
Comment monter en scalabilité ?
On ne peut pas mettre plusieurs machines sur le diagramme de composants.
Le diagramme de déploiement montre les machines.
Par exemple 3 machines
Rest-service : il faut une URL qui contient un nom de machine et un port
Synthese de l’architecture:
Appli web
Load balancer
2 machines de conversions
Une question? Posez-la ici
Attention, le load balancer est un composant critique, SPOF (single point of failure) et devra être redondé et répliqué
S’il tombe, il en faut plusieurs, au moins 2.
Objectifs :
Parallélisme
Asynchronisme
Sur le load balancer, on applique le pattern d’architecture distribuée « file de message » pour qu’il serve de répartition de charge. Pattern QCENTRIC avec une partie production sur le LB et une partie consommation sur le convertisseur.
Traitement redondé, copié
Traitement répliqué : traitement redondé et IDENTIQUE
Comment est-ce que le load balancer connait les machines convertisseurs ?
Hypothèse1 : le fichier properties
Créer un composant fichier properties avec les 3 adresses
On va faire du round robin
Une application réseau est différente d’une application distribuée.
Si on ajoute un convertisseur, on le rajoute dans le fichier properties
Si on supprime un convertisseur, on le supprime dans le fichier properties
Si le fichier propreties est modifié, on le relit donc toutes les 30 secondes et si on ajoute un convertisseur, il est pris en compte. Idem si on le supprime le fichier convertisseur.
C’est une application « réseau », pas distribuée. Car on ne gère pas le cycle de vie dégradé : elle n’est pas autonome ; On ne peut pas enlever et rajouter des composants de manière transparente. En application réseau, si l’application tombe « message d’erreur pourri » et le service s’arriête.
On va mettre le fichier properties de côté.
Une question? Posez-la ici
Hypothèse2 : le registry
New component : registry
Chaque convertisseur se connecte au registry et lui dit quelle hostname/url il est, et il mets ca dans une liste en mémoire.
Le portail vient récupérer cette liste dans le registry
Mais il y a encore un spof
Avantage par rapport au properties : une fois que l’url du registry est connue dans le converter c’est bon.
Diagramme de séquences
Que se passe-t-il ?
Le convertisseur fait « Inscription » sur le registry quand il est disponible
Le convertisseur fait « unInscription » sur le registry quand il est indisponible
Phase développement
Développer le système en java : charge de travail de 15h de dev
Coté converter : soit en RMI c’est très simple, soit en REST.
Ca serait bien de parir sur du REST, mais c’est dur, on va exploser les 15h du planning poker agile de la planification agile.
Le langage on s’en fiche, on peut le faire en python, .net si on préfère...
Ce qu’il faut c’est avant tout un bon algo
EN RMI tout est implémenté, la liste, la méthode Inscription...
Le serveur convertisseur donc avoir une seule méthode « startConverter » qui fait juste un envoi de message
Le Client java a juste une class avec un main qui représente une webapp
Si ce n’est pas un joli code, pas grave, on l'améliorera en reafctoring à la phase de revue de code
Implementer le mécanisme de listes régulier
Implementer le mécanisme d’enregistrement du registry régulier
Il faut raisonner en objectifs : objectifs scenario : arreter le registry et constater que ca marche encore.
1ere chose à implementer le client s’enregistre
2eme chose à implementer : si j’arrête mon registre, est-ce que ca continue de marcher ?
On implemente un objet Converter
Pas obligé de faire du threading
Je vois bien 3 programmes :
-1 webapp portail
Méthode getStatus, demande au convertisseur où en est le pourcentage de conversion, retourne un INT (pourcentage)
-1 registry load-balancer, liste des convertisseurs en mémoire
-1 convertisseur video
Méthode StartConversion, démarre la conversion asynchrone
Je choisis de le faire en Java car j’ai déjà travaillé avec RMI.
Un objet distant (remote object) est instancié à partir d’une classe sur un serveur, qui implémente l’interface à distance (remote interface).
L’interface à distance (remote interface) étend l’interface java.rmi.remote et déclare un ensemble de méthodes qui peuvent être appelées à distance.
Si un objet étend l’interface java.rmi.remote, il est accessible à distance
Chaque méthode déclare java.rmi.RemoteException dans son throws
A la différence d’un appel d’une méthode en local, l’appel d’une méthode à distance est délicat, car cet appel ne peut pas aboutir vu certains soucis réseau qui peuvent surgir (panne de routeurs…). Donc on doit catcher ces problèmes réseau en throwant une java.rmi.RemoteException
La méthode sayHello pourra-être appelée à distance
Implementation du serveur
Le serveur a une classe main qui instancie un objet que l’on doit pouvoir interroger à distance, et lie cet instance dans le JAVA RMI registry (annuaire serveur rmi pour le rendre visible aux autres programmes, sur le port 1099).
Classe server (convertisseur) qui implemente qui implemente la remote interface hello (start conversion)
J’aurais pu faire un import java.rmi.*
Le serveur implémente l’interface Hello, implémentation de la méthode distante sayHello.
Attention, les méthodes dans la classe qui ne sont pas spécifiées dans l’interface ne peuvent pas être appelées à distance.
La classe UnicastRemoteObject permet de créer le stub (objet virtuel) de l’objet serveur distant avec la méthode UnicastRemoteObject
Obj est une instance de notre classe serveur, un objet en mémoire sur le serveur.
On crée le stub, ou souche en français : c’est l’image virtuelle de l’objet distant
Le skeleton est créé.
Le stub (côté client) marshalise les données vers le skeleton (côté serveur)
skeleton (côté serveur) démarshalise les données du stub. Il execute la méthode. Le resultat de l’execution de la méthode est sérialisé, marshallé, et est envoyé vers le stub. Le stub désérialise et transmet au client (à l’objet) le résultat de la méthode appelée à distance.
La méthode main du serveur doit instancier l’objet dont la méthode va être appelée à distance.
Cet objet doit être exporté dans le runtime RMI pour qu’il puisse rendre disponible ses méthodes à distance. On effectue ceci comme cela :
Server obj = new Server();
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);
Le serveur écoute les demandes sur un port TCP grâce à un socket.
Le serveur réagit aux demandes et renvoie le stub au client, qui contient le hostname et le port par lequel l’objet distant peut être contacté.
Besoin d'aide en infrastructure distribuée?
Remplissez ce formulaire