Client / Serveur, LP MRIT 2020 - 2021

Plan du cours


Préambule

Sockets

Python

Go

Rust

Redis

Dissertations

Conclusion


Préambule

L'évaluation du module consiste à rédiger un compte rendu de TP reprenant l'ensemble des manipulations que vous allez faire. Pour édiger un compte rendu de TP, il est opportun de suivre les recommandations suivantes :

Le cours traite du modèle Client / Serveur. L'environnement client–serveur désigne un mode de communication à travers un réseau entre plusieurs programmes : l'un, qualifié de client, envoie des requêtes ; l'autre, qualifié de serveur, attend les requêtes des clients et y répond. C'est le serveur qui résout le problème posé (à travers la requête du client) par le client. Ainsi le serveur est généralement une machine avec des capacités importantes (CPU, RAM, disque...) alors que le client tourne sur une machine beaucoup moins performante, par exemple un Smartphone. L'exemple le plus parlant est par exemple l'interrogation de Google via votre Smartphone.

Nous allons d'abord aborder la notion de Socket. C'est une notion introduite il y a de nombreuses années dans le cadre d'Unix BSD. Ensuite nous déclinerons la notion dans les environnements Python, Go, Rust et Redis. Nous abordons donc la problématique sous l'angle de la programmation. Nous pourrions l'aborder dans le cadre des architectures Client / Serveur. Pour l'instant cela nous amènerait trop loin. Il serait alors nécessaire de parler d'architecture pair à pair, multi-niveaux voire d'architecture logicielle pour le développement de composants Client / Serveur. De même nous de parlerons pas du mode de communication RMI (Remote method invocation) qui est une interface de programmation (API) issue du langage Java qui permet d'appeler des méthodes (programmes) distantes. De même nous ne parlerons pas de RPC (Remote procedure call). En informatique et en télécommunication, RPC est un protocole réseau permettant de faire des appels de procédures sur un ordinateur distant à l'aide d'un serveur d'applications. Ce protocole est utilisé dans le modèle client-serveur pour assurer la communication entre le client, le serveur et d’éventuels intermédiaires. Tout ceci est laissé pour vos études ultérieures. Cependant, cela permet de replacer notre cours dans un contexte général. Enfin, si vous cherchez un livre dinosaure, je ne peux que vous recommander The Essential Client/Server Survival Guide de Robert Orfali.

Vous pouvez maintenant écouter le Podcast introductif qui reprend et précise le texte ci-dessus. Cliquer sur le bouton 'Play' pour l'écouter.


Sockets

Pour commencer avec la communication par Sockets, rien ne vaut la lecture de ces quelques transparents par Sacha Krakowiak, un expert français, une des premières personnes ayant travaillé en recherche en France sur les systèmes d'exploitation. A ce sujet, je ne peux que vous recommander d'écouter les Podcasts sur la page suivante du Monde.

Pour en revenir aux Sockets, Sacha Krakowiak commence par exposer le réseau vu du côté de l'utilisateur, puis précise la place des Sockets dans le modèle OSI. Il passe ensuite à la description des Sockets côté serveur. Le transparent 9-11 résume l'API côté serveur. La suite concerne le côté client, à partir de la page 9-12. Un résumé de l'API côté client est présenté au transparent 9-14. Pour simplifier l'écriture de programme (ici en C), Sacha Krakowiak utilise des raccourcis qui sont implémentés dans le fichier csapp.c / csapp.h. Les transparents 9-19 et 9-20 reprennent le modèle d'interaction des Sockets. Ces transparents sont importants. Le document se poursuit par une discussion courte sur comment faire un serveur qui accepte des requêtes concurrentes. Vous pouvez passer car non central au début. Les transparents se terminent par les codes de certaines fonctions introduites au cours de la discussion.

Pour recoller les différents morceaux de code, vous pouvez aussi lire ce livre en anglais à partir de la page 900. Pour les codes à faire tourner par vos soins, voir l'archive tiny.tar disponible en suivant ce lien (voir en bas de la page HTML). Comme il s'agit de codes source écrits en langage C il vous faudra apprendre rapidement quelques éléments de C, par exemple en suivant la page Unix / C. Il convient également de savoir se servir, en ligne de commande, d'un compilateur C. Voir par exemple ces quelques lignes explicatives. L'archive tiny.tar comporte un fichier README qui, comme son nom l'indique, vous invite à le parcourir afin de découvrir ce que vous pouvez faire avec l'archive.

En résumé, pour cette partie de votre compte rendu de TP, vous devez expliquer comment vous vous êtes servi de tiny.tar pour simuler un client et un serveur Web, implémentés avec les Sockets. Il faut donc lire, comprendre, tester ce code... et en faire un résumé compréhensible par le commun des mortels. Vous pouvez aussi lire la page en anglais Network socket.

Autrement dit, à l'issue du premier TP vous devriez avoir traité à minima les choses suivantes :

  • Écouter le Podcast ;
  • Lire et comprendre le poly de Krakowiack ; La partie technique concerne comment on met en place un canal de communication selon le modèle original des Sockets tel qu’il est apparu dans BSD il y a presque 40 ans. Cette partie technique est décrite à partir de la page 8-8 des transparents ;
  • Faire tourner le code tiny.tar. C’est un code en C.
  • Commenter ce code avec VOS COMMENTAIRES PERSONNELS ; C'est ce que je vais apprécier en premier lieu ; Il ne s'agit pas de faire un commentaire ligne par ligne mais de dégager la structure, la nature du code (l'ensemble des caractères qui constituent réellement le code, ce qui est important) ;
  • Rédiger le compte rendu selon les recommandations ci-dessus ; C'est ce que je vais apprécier en second lieu.

Les autres liens Hypertext sont donnés comme des extras. Enfin, les TPs qui suivent ce premier TP, peuvent suivre également cette organisation et les éléments méthodologiques associés : lire et comprendre une notion (API), expérimenter avec un code donné, commentaires personnels sur le code afin de montrer que vous vous l'êtes approprié, rédaction du compte rendu.

Python et la programmation client / serveur

Python, vous le connaissez en long en large et en travers. Vous l'avez beaucoup pratiqué en début d'année. Vous allez pouvoir passer directement au TP Socket Programming in Python. Ce TP en ligne débute par des rappels sur le modèle des Sockets et l'API (socket(), bind(), listen(), accept()). Ensuite il y a la description de comment faire pour gérer plusieurs requêtes concurrentes. On discute alors des I/O asynchrones. Cette notion intervient parce que nous allons utiliser send() et recv(). A partir de là, la discussion devient plus technique. La partie qui suit vise à contrôler les payoff. Vous vous arrêterez avant la lecture de la section Troubleshooting. Pour information, le module Python Sockets est décrit en suivant le lien.

Je ne vous demande pas d'être un expert en programmation Python ou Go ou Rust ou Redis... mais d'être capable de rejouer des codes et de faire un commentaire qui n'est pas une paraphrase (phrase synonyme d'une autre). Par exemple, commenter i = i + 1 par la variable i est incrémentée de 1 n'apporte pas grand chose pour comprendre le code complet. Je vous demande de faire un effort sur ce que vous observez, à la lumière des notions générales, c'est-à-dire de prendre un peu de hauteur. Voici un exemple qui concerne une partie du texte sur les sockets non bloquantes en Python (#multi-connection-client-and-server). Veuillez noter en particulier comment je monopolise mes connaissances en réseau.

Il semblerait qu’il y ait un problème dans le code du client. En effet le client ne reçoit pas tous les messages émis par le serveur. Dans l’exemple, dont la trace d'exécution est ci-après, le serveur émet 6 fois alors que le client ne reçoit que 4 messages. Que peut-il se passer ?

  MBPdeChristophe:Desktop christophecerin$ python3 multiconn-client.py localhost 9000 3
  starting connection 1 to ('localhost', 9000)
  starting connection 2 to ('localhost', 9000)
  starting connection 3 to ('localhost', 9000)
  sending b'Message 1 from client.' to connection 1
  sending b'Message 1 from client.' to connection 2
  sending b'Message 2 from client.' to connection 1
  sending b'Message 2 from client.' to connection 2
  sending b'Message 1 from client.' to connection 3
  received b'Message 1 from client.Message 2 from client.' from connection 1
  sending b'Message 2 from client.' to connection 3
  received b'Message 1 from client.Message 2 from client.' from connection 2
  received b'Message 1 from client.' from connection 3
  received b'Message 2 from client.' from connection 3
  ^Ccaught keyboard interrupt, exiting
  MBPdeChristophe:Desktop christophecerin$ python3 multiconn-client.py localhost 9000 3
  starting connection 1 to ('localhost', 9000)
  starting connection 2 to ('localhost', 9000)
  starting connection 3 to ('localhost', 9000)
  sending b'Message 1 from client.' to connection 1
  sending b'Message 1 from client.' to connection 2
  sending b'Message 1 from client.' to connection 3
  sending b'Message 2 from client.' to connection 1
  sending b'Message 2 from client.' to connection 2
  sending b'Message 2 from client.' to connection 3
  received b'Message 1 from client.' from connection 1
  received b'Message 2 from client.' from connection 1
  received b'Message 1 from client.Message 2 from client.' from connection 2
  received b'Message 1 from client.Message 2 from client.' from connection 3



  MBPdeChristophe:Desktop christophecerin$ python3 multiconn-server.py localhost 9000
  listening on ('localhost', 9000)
  accepted connection from ('127.0.0.1', 50494)
  accepted connection from ('127.0.0.1', 50495)
  accepted connection from ('127.0.0.1', 50496)
  echoing b'Message 1 from client.' to ('127.0.0.1', 50494)
  echoing b'Message 1 from client.' to ('127.0.0.1', 50495)
  echoing b'Message 2 from client.' to ('127.0.0.1', 50494)
  echoing b'Message 2 from client.' to ('127.0.0.1', 50495)
  echoing b'Message 1 from client.' to ('127.0.0.1', 50496)
  echoing b'Message 2 from client.' to ('127.0.0.1', 50496)
  closing connection to ('127.0.0.1', 50494)
  closing connection to ('127.0.0.1', 50495)
  closing connection to ('127.0.0.1', 50496)
  accepted connection from ('127.0.0.1', 50521)
  accepted connection from ('127.0.0.1', 50522)
  accepted connection from ('127.0.0.1', 50523)
  echoing b'Message 1 from client.' to ('127.0.0.1', 50521)
  echoing b'Message 1 from client.' to ('127.0.0.1', 50522)
  echoing b'Message 1 from client.' to ('127.0.0.1', 50523)
  echoing b'Message 2 from client.' to ('127.0.0.1', 50521)
  echoing b'Message 2 from client.' to ('127.0.0.1', 50522)
  closing connection to ('127.0.0.1', 50521)
  echoing b'Message 2 from client.' to ('127.0.0.1', 50523)
  closing connection to ('127.0.0.1', 50522)
  closing connection to ('127.0.0.1', 50523)
  accepted connection from ('127.0.0.1', 50539)
  accepted connection from ('127.0.0.1', 50540)
  accepted connection from ('127.0.0.1', 50541)
  echoing b'Message 1 from client.' to ('127.0.0.1', 50539)
  echoing b'Message 2 from client.' to ('127.0.0.1', 50539)
  echoing b'Message 1 from client.Message 2 from client.' to ('127.0.0.1', 50540)
  echoing b'Message 1 from client.' to ('127.0.0.1', 50541)
  echoing b'Message 2 from client.' to ('127.0.0.1', 50541)
  closing connection to ('127.0.0.1', 50540)
  closing connection to ('127.0.0.1', 50541)
  closing connection to ('127.0.0.1', 50539)
  accepted connection from ('127.0.0.1', 50543)
  accepted connection from ('127.0.0.1', 50544)
  accepted connection from ('127.0.0.1', 50545)
  echoing b'Message 1 from client.' to ('127.0.0.1', 50543)
  echoing b'Message 2 from client.' to ('127.0.0.1', 50543)
  echoing b'Message 1 from client.Message 2 from client.' to ('127.0.0.1', 50544)
  echoing b'Message 1 from client.Message 2 from client.' to ('127.0.0.1', 50545)

Le code est correct. L’explication qui fait que le nombre d'émissions par le serveur peut être supérieur au nombre de réceptions par le serveur est la suivante. Premièrement observons intuitivement nous pourrions penser que nous avons potentiellement des pertes d’information avec une telle situation, voire une situation de blocage du coté du client (attente infinie des messages restant à recevoir). En fait nous observons que des informations ont été concaténées dans un seule message si bien qu’il n’y a pas eu de perte d’information dans l’exécution transmise en copie. Deuxièmement, puisque nous avons choisi (cf code) une socket non bloquante, le scénario suivant est possible. Deux messages du serveur en direction du client sont déposés dans le buffer d'émission, coté serveur car le client n’était pas prêt à recevoir. Lorsque celui-ci est prêt, il récupère tous les objets (messages concaténés) déposés dans le buffer d'émission (taille limitée à 1024 bytes dans le code initial). Ainsi, c’est seulement une seule réception qui a permis de réceptionner 2 messages émis.

La trace d'exécution qui est jointe ci-après correspond aux codes joints (code 1 et code 2) où j’ai fixé la taille du buffer de réception, côté client, à 22 ce qui correspond exactement à la taille de chacun des messages. Dans ce cas, l'émetteur (coté serveur) ne peut déposer que 22 bytes dans le buffer d'émission. S’il y a des autres demandes d'émission sur la socket, elles sont mises en attente jusqu'à ce que le buffer soit lu (du côté du client). Ainsi, la trace d’exécution obtenue correspond à une situation où on a exactement le même nombre d’echoing (9 coté serveur) que de réceptions (9 coté client). C’est un biais lié au choix de cette valeur 22.

Pour terminer cette discussion, le mode non bloquant est inadapté si vous voulez transmettre un fichier depuis le serveur vers un client. Il y a des risques pour que la réception des informations ne corresponde pas à l’ordre des émissions, et donc vous allez produire un fichier « où les informations seront désordonnées par rapport au fichier initial ». N’oubliez pas également que les écritures sur le disque peuvent être bloquantes (on dit aussi synchrone) ou non bloquantes (on dit aussi asynchrone). Dans le premier cas vous contrôlez l’ordre des écritures sur le disque, dans l’autre cas, pas du tout.

La trace obtenue en fixant la taille du buffer de réception à 22 côté client est la suivante :

  MBPdeChristophe:Desktop christophecerin$ python3 multiconn-server.py localhost 9000
  listening on ('localhost', 9000)
  accepted connection from ('127.0.0.1', 53422)
  accepted connection from ('127.0.0.1', 53423)
  accepted connection from ('127.0.0.1', 53424)
  echoing b'Message 1 from client.' to ('127.0.0.1', 53422)
  echoing b'Message 1 from client.' to ('127.0.0.1', 53423)
  echoing b'Message 2 from client.' to ('127.0.0.1', 53422)
  echoing b'Message 2 from client.' to ('127.0.0.1', 53423)
  echoing b'Message 1 from client.' to ('127.0.0.1', 53424)
  echoing b'Message 3 from client.' to ('127.0.0.1', 53422)
  echoing b'Message 3 from client.' to ('127.0.0.1', 53423)
  echoing b'Message 2 from client.' to ('127.0.0.1', 53424)
  closing connection to ('127.0.0.1', 53422)
  closing connection to ('127.0.0.1', 53423)
  echoing b'Message 3 from client.' to ('127.0.0.1', 53424)
  closing connection to ('127.0.0.1', 53424)


  MBPdeChristophe:Desktop christophecerin$ python3 multiconn-client.py localhost 9000 3
  starting connection 1 to ('localhost', 9000)
  starting connection 2 to ('localhost', 9000)
  starting connection 3 to ('localhost', 9000)
  sending b'Message 1 from client.' to connection 1
  sending b'Message 1 from client.' to connection 2
  sending b'Message 2 from client.' to connection 1
  sending b'Message 2 from client.' to connection 2
  sending b'Message 1 from client.' to connection 3
  sending b'Message 3 from client.' to connection 1
  sending b'Message 3 from client.' to connection 2
  sending b'Message 2 from client.' to connection 3
  sending b'Message 3 from client.' to connection 3
  received b'Message 1 from client.' from connection 1
  received b'Message 1 from client.' from connection 2
  received b'Message 2 from client.' from connection 1
  received b'Message 2 from client.' from connection 2
  received b'Message 1 from client.' from connection 3
  received b'Message 3 from client.' from connection 1
  closing connection 1
  received b'Message 3 from client.' from connection 2
  closing connection 2
  received b'Message 2 from client.' from connection 3
  received b'Message 3 from client.' from connection 3
  closing connection 3

Go et la programmation client / serveur

Go est un langage de programmation compilé et concurrent inspiré de C et Pascal. Ce langage a été développé par Google à partir d'un concept initial de Robert Griesemer, Rob Pike et Ken Thompson. J'ouvre une parenthèse sur Ken Thompson. Il a travaillé sur les systèmes d'exploitation à temps partagé, notamment Multics, puis Unix à partir de 1969 et plus tard Plan 9. En 1970, il met au point le langage B, précurseur du C. Quand j'étais plus jeune qu'aujourd'hui, j'apprenais la programmation C à partir du livre The C Programming Language. J'ai surtout connu la deuxième édition du livre, celle de 1988. Je ne suis pas assez vieux pour avoir connu la première édition, celle de 1978. Fin de la parenthèse.

Commencer par installer Go en suivant ce tutoriel. Ensuite vous pouvez faire le test que tout fonctionne correctement avec le programme qui affiche Hello World!, toujours en suivant les instructions du tutoriel.

Passer ensuite au TP qui vise à créer un client et un serveur (TCP et UDP) en Go. Vous allez retrouver des mots clés connus comme Listen. Vous noterez que le modèle est un peu différent du modèle des Sockets. Dans votre compte rendu de TP il sera utile et indispensable de commenter les lignes des programmes. Attention, l'activité de commentaire n'est pas l'activité de paraphraser le code. Il faut commenter des blocs d'instructions plutôt que chacune des lignes. En fait vous devez montrer que vous avez repéré les grandes structures organisationnelles du programme (les boucles, les conditionnelles...) et comment elles s'articulent les unes avec les autres pour établir une communication selon le modèle des Sockets.

Rust et la programmation client / serveur

Rust est un langage de programmation compilé multi-paradigme (procédural, fonctionnel, modèle d'acteur...) conçu et développé par Mozilla Research. Il a été conçu pour être « un langage sécurisé, concurrent, pratique ». Le langage peut notamment donner des garanties d'absence d'erreur de segmentation ou de situation de concurrence (interblockage). De plus, ceci se fait sans ramasse-miettes (Garbage collector). Enfin, Rust est accompagné de Cargo, un gestionnaire de paquets permettant de gérer la compilation et les dépendances entre paquets.

Il n'est pas vraiment utile d'apprendre le langage pour notre cours car vous allez essentiellement exécuter des codes existants. Commencer par installer Rust et ensuite faites quelques exercices, par exemple le Hello world!.

Enfin, passez aux pages expliquant comment construire un Server Web multithrédé. Ce TP est composé de 3 sections afin de vous amener progressivement vers la solution. Il s'agit d'abord d'exposer ce qu'est TCP et HTTP. Ensuite on vous explique comment implémenter un serveur Web qui traite les requêtes les unes après les autres (Single-Threaded Web Server). Enfin, l'article vous montre comment faire en sorte que le serveur Web puisse traiter plusieurs requêtes concurremment. A priori il faut lire, comprendre, faire des copier coller de ce qui est présenté, tester. Vous allez retrouver des mots clé vus précédemment comme bind, d'autres peut être inconnus pour vous comme listener. Je serais sur Discord pour répondre à vos questions.

Redis

Redis va être l'occasion de discuter de ce qui se passe lorsque plusieurs clients veulent accéder à une ressource partagée située sur le serveur et de discuter aussi des mécanismes de retour arrière. Ce dernier mécanisme, bien connu des personnes travaillant en base de données, est un modèle pour traiter les exceptions, c'est à dire de quelque chose qui est "mauvais" pour le programme et les données.

Redis (de l'anglais REmote DIctionary Server qui peut être traduit par « serveur de dictionnaire distant ») est un système de gestion de base de données clé-valeur scalable, très hautes performances (il peut gérer 10000 sockets), écrit en C ANSI. Il fait partie de la mouvance NoSQL (not only sql). NoSQL désigne une famille de systèmes de gestion de base de données (SGBD) qui s'écarte du paradigme classique des bases de données relationnelles comme on peut l'observer avec les SGBD MySQL, MariaDB, PostgreSQL, SQLite... qui visent à organiser les données sous forme de tables.

Commencer par installer Redis, puis faites les quelques manipulations suggérées sur cette page.

Imaginons maintenant que nous avons plusieurs clients voulant accéder pour lire ou modifier une ressource partagée, et située sur le serveur. L'ordre dans lequel les clients accèdent à cette ressource partagée peut avoir de l'importance quand il s'agit d'opérations de modification. Par exemple si le client 1 écrit la valeur 5 puis le client 2 la valeur 12 dans la variable partagée P, alors ce n'est pas la même chose que si c'est d'abord le client 2 qui opère, puis le client 1. En fait, nous avons besoin de la notion d'opération atomique pour garantir un accès exclusif à la ressource partagée. Pour comprendre les problèmes, liés à la technologie Redis, vous lirez la page suivante et vous ferez les exercices suggérés pour les opérations atomiques (appending to a string,...,getting the member with hihest ranking in a sorted set). Vous pouvez aussi vous familiariser avec la notion d'atomicité avec Redis en lisant ce tutoriel.

Pour contrôler l'exécution de groupes d'instructions, Redis implémente une notion de transaction. Faites les manipulations suggérées sur cette page. N'oubliez pas d'expliquer clairement quels sont les problèmes que la notion permet de capter. Et faites simple s'il vous plaît ! Pour votre compte rendu, vous ne parlerez que de ce que vous comprenez dans cette page ! Pas d'explication tarabiscotées.

Pour la partie liée aux transactions, veuillez lire cette note technique. Pour exposer un serveur Redis sur Internet et qu'il génère des logs, vous pouvez le lancer de la manière suivante (voir le fichier redis.conf dans les sources) :

$ redis-server --loglevel verbose --protected-mode no

Dissertations

Pour tous les sujets qui vous sont maintenant proposés, il conviendra de problématiser, de poser des arguments, les discuter et les mettre en relation. Il ne s'agit donc plus de rester au niveau d'un commentaire comme précédemment. Vous devez donc trouver le problème général que le sujet évoque et discuter des pistes pour le résoudre. C'est seulement ensuite que vous pourrez discuter de la technique. Autrement dit, une fois le problème identifié, posez-vous la question de ce qu'il convient de faire pour le traiter, puis du comment le faire. Le volet dissertation viendra en complément du travail technique que nous présentons maintenant.

Sujet 1 : échange de flux vidéo

Au moment on j'écris ce cours nous sommes en pleine période de Coronavirus. Pour travailler à distance nous avons besoin d'outils de visioconférences. La norme HTML5 permet à votre navigateur d'afficher et de jouer de la vidéo et du son. Ce n'est pas exactement ce que nous voulons. Nous voulons pouvoir échanger des flux audio/vidéo entre navigateurs, et ceci en temps réel. Pour cela nous avons la technologie WebRTC. A partir de la page suivante, vous mettrez en lumière l'architecture client / serveur sous-jacente à WebRTC. Il peut être utile de vous aider de la page suivante de l'IETF ou de celle parlant de la technologie STUN. Vous devez disserter sur au plus 2 pages, pas une de plus. Il convient de disserter sur le plan de l'architecture d'un système permettant l'échange de flux audio/vidéo. Soyez concis et précis.

HINT : vous pouvez consulter l'outil Coturn qui est une "Free open source implémentation of TURN and STUN Server".

Sujet 2 : RMI

Dans le monde Java, la technologie RMI (Remote Methode Invocation) est une interface de programmation (API) permet d'appeler des méthodes (donc des programmes) distantes. Cette bibliothèque, qui se trouve en standard dans Java Standard Edition (SE), permet la communication via le protocole HTTP (ou IIOP, depuis la version 1.3 du JDK) entre des objets Java éloignés physiquement les uns des autres, autrement dit s'exécutant sur des machines virtuelles java distinctes. RMI facilite le développement d'applications distribuées en masquant au développeur la communication client / serveur.

Vous commencerez par lire ces éléments introductifs sur la technologie RMI.

Vous travail consiste à faire une synthèse de ce qui est expliqué sur la page suivante qui est un tutoriel sur RMI construit à partir d'un exemple. Je vous demande en particulier de montrer que vous avez réussi à faire tourner l'exemple. Vos commentaires sont, bien entendu, personnels. Il ne s'agit pas de paraphraser les termes de l'exemple. Je vous propose également de faire un schéma expliquant l'architecture logicielle de l'exemple i.e. les composants et les liens de communication entre ces composants. Ce schéma sera discuté, légendé et référencé dans le texte que vous proposez à votre lecteur. Je rappelle que tout schéma ou figure ne sont jamais donnés à titre gratuit. Ils sont là pour appuyer une explication.

Conseils : pour installer les outils de développement liés à la technologie Java, je vous propose d'utiliser l'outil SDKman. Vous allez pouvoir installer un compilateur Java et des outils pour le développement d'applications en Java.

Sujet 3 : collectd – The system statistics collection daemon

collectd est un démon (un type de programme informatique, un processus ou un ensemble de processus qui s'exécute en arrière-plan plutôt que sous le contrôle direct d'un utilisateur) qui collecte périodiquement les mesures de performance du système d'exploitation et des applications. Il fournit des mécanismes permettant de stocker les valeurs d'utilisation des ressources du système de diverses manières, par exemple dans le format des fichiers RRD. L'objectif de votre dissertation est d'expliquer comment installer, configurer et utiliser collectd. Par exemple, il peut être utilisé via un serveur Web ou via une interface de programmation (API).

Votre travail consiste à :

  • Installer et configurer collectd ;
  • Installer et configurer le plugin Apache. Attention, il peut y avoir des dépendances ! Montrer via des captures d'écran que vous accédez à des informations collectées et exposées par le serveur Apache ;
  • Installer et configurer le plugin Python. Faites un exemple où un script Python affiche des données collectées ;
  • Présenter sur une page (max) le format RRD et les outils de manipulation de ce format ;
  • Synthétiser tout ce que vous avez fait dans un document qui doit en particulier mettre en évidence les liens qui existent entre les différents points ci-dessus et comment intervient la notion de client/serveur.

Conclusion

Le Podcast suivant sert de conclusion générale. Veuillez cliquer sur le bouton 'Play' pour l'écouter.

Enfin, pour aller encore plus loin, et si vous avez le temps, je vous recommande la lecture de l'article OSI: The Internet That Wasn’t et le TP How to Use Redis With Python.