gRPC, pionnier de la communication client/serveur de l’avenir

La technologie de réseau progresse de plus en plus rapidement. Pour satisfaire les exigences croissantes des systèmes informatiques distribués, un nouveau système, appelé gRPC, a été mis au point pour la gestion des appels Remote Procedure Calls. Le « g » représente la contribution considérable de Google au développement de ce protocole. Découvrez ici ce qu’est le gRPC, comment il fonctionne et où il est utilisé.

Qu’est-ce que le gRPC ?

Le gRPC est un système d’appels Remote Procedure Call permettant une communication particulièrement efficace au sein d’architectures client/serveur distribuées grâce à des technologies de procédés innovants. Tout comme son prédécesseur le RPC, il fonctionne au niveau des processus. La caractéristique de la communication inter-processus via gRPC est le principe de transparence : la relation entre les instances (partiellement) éloignées se veut aussi étroite et simple qu’une communication locale entre plusieurs processus internes d’une même machine.

Le gRPC a été mis au point par Google en 2015. Aujourd’hui, la Cloud Native Computing Foundation prend en charge la diffusion et le développement de cette technique de communication. Le gRPC est Open Source, ce qui signifie que son texte source fait partie du domaine public, les tiers sont autorisés et même encouragés à le modifier et à en poursuivre le développement.

Le gRPC traite de manière normalisée le transport de flux de données entre des ordinateurs distants via le protocole HTTP/2. Les Protocol Buffers développés par Google prennent en charge la structuration et le traitement des données. Ces derniers sont enregistrés sous forme de simples fichiers textes portant l’extension .proto.

Le gRPC est souvent entendu comme un framework. L’une des particularités d’un framework est qu’il met un cadre de programmation à disposition de ses développeurs, épargnant ainsi du temps et des efforts. La structure normalisée de gRPC intègre déjà différents éléments et fonctions qu’il n’est alors pas nécessaire de toujours reprogrammer. Le framework gRPC définit en outre des interfaces normalisées pour des sources définies (par exemple bases de données).

Fonctionnement du gRPC : multilingue et efficace via les Protocol Buffers et HTTP/2

Les Protocol Buffers (Protobuf) remplissent plusieurs fonctions au sein du système gRPC : ils servent d’Interface Definition Language (langage de description d’interface, abr. : IDL), décrivant une interface indépendamment de son langage. Ils ne sont donc pas liés à un langage de programmation spécifique (par exemple Java ou C). Ils définissent en outre les services à utiliser et les fonctions mises à disposition. Pour chaque fonction, les paramètres envoyés avec une requête ainsi que la valeur de retour attendue peuvent être indiqués.

S’alignant sur la perspective de la communication entre ordinateurs distants, les Protocol Buffers servent de format d’échange de messages de base déterminant les structures, types et objets des messages. Ils assurent que le client et le serveur se « comprennent » et peuvent opérer conjointement, de manière fonctionnelle et aussi performante que possible, malgré la distance.

Le déroulement d’un appel gRPC est le suivant lors de la consultation d’une base de données (par exemple « Recherche d’un stock d’articles à l’entrepôt ») :

  • Avant de pouvoir exécuter la recherche, des préparatifs sont nécessaires. Côté serveur, sur la base des Protocol Buffers, on implémente d’abord un service et un serveur gRPC. Le client auteur de la requête génère de son côté un stub correspondant. Lorsque ce dernier est disponible, l’application client appelle la fonction correspondante (« Recherche de stock d’articles ») dans le stub.
  • La requête est ensuite envoyée au serveur via le réseau. Après réception à l’aide d’une interface de service adaptée, le serveur gRPC démarre la recherche de produits réelle dans la base de données.
  • Le serveur envoie alors la réponse au stub client, qui retransmet la valeur de retour à l’instance demandeuse d’origine (par exemple « Nombre d’articles trouvés »).

Les applications côté client et côté serveur peuvent être écrites dans différents langages de programmation. Le gRPC surmonte ces obstacles à l’aide d’interfaces et de mécanismes de traduction spéciaux.

Pour l’échange de flux de données entre machines (Proto Request et Proto Response), le protocole HTTP/2 est intégré à des protocoles réseau spéciaux, tels que TCP/IP ou UDP/IP. Les flux de données transfèrent les données binaires compactes générées lors de la sérialisation (Marshalling) typique des Remote Procedure Calls. Pour le traitement complet des structures de données abstraites côté client et côté serveur en plusieurs étapes, les flux transmis sont également désérialisés (Unmarshalling).

Workflow gRPC et premières étapes via Protocol Buffers

Le Workflow gRPC typique est divisé en quatre étapes :

  1. Définition du contrat de service pour la communication inter-processus : détermination des services à appliquer, ainsi que des paramètres et types de réponse principaux susceptibles d’être appelés à distance.
  2. Génération du code gRPC à partir du fichier .proto : des compilateurs spéciaux (outils de ligne de commande nommés « protoc ») génèrent le code opérationnel de la classe correspondante d’un langage cible souhaité à partir des fichiers .proto enregistrés (par exemple C++, Java).
  3. Implémentation du serveur dans le langage sélectionné.
  4. Création du stub client pour l’appel du service ; la ou les requête(s) est/sont ensuite exécutée(s) via le serveur et le ou les client(s).

Lors de la consultation d’une base de données recherchant un produit en stock (inventory), les premières étapes concrètes sont indiquées comme suit dans la syntaxe actuelle des Protocol Buffers (version : proto3) :

syntax = "proto3";
package grpc_service;
import "google/protobuf/wrappers.proto";
service InventoryService {
	rpc getItemByName(google.protobuf.StringValue) returns (Items);
	rpc getItemByID(google.protobuf.StringValue) returns (Item);
	 rpc addItem(Item) returns (google.protobuf.BoolValue);
}
 
message Items {
  string itemDesc = 1;
  repeated Item items = 2;
}
 
message Item {
	string id = 1;
	string name = 2;
	string description = 3;
}

Dans l’exemple, la consultation de la base de données passe par les « bibliothèques Wrapper » spéciales du framework gRPC, importées dès le départ et mettant à disposition les procédures de traduction préprogrammées correspondantes. Au sein d’architectures client/serveur multilingues et diverses, celles-ci assurent la communication entre des interfaces autrement incompatibles. C’est ainsi que sont générées les classes nécessaires à la lecture et à l’écriture de messages.

La manière dont la définition des services (inventory.proto) régule la consultation d’une base de données au sein d’une architecture serveur/client est expliquée dans l’aperçu suivant :

HTTP/2 : streaming à performance optimisée

Le protocole HTTP/2 tient un rôle central dans le gRPC, car il permet le transfert de données binaires compactes et l’échange particulièrement efficace de messages et de données. Le protocole réseau met à disposition quatre variantes de Remote Procedure Calls :

1. Les RPC unaires forment le modèle de gRPC le plus simple. Le client émet une demande individuelle au serveur. Comme pour tout appel fonctionnel normal, il reçoit ensuite une réponse individuelle.

Exemple : rpc SayHello (HelloRequest) renvoie (HelloResponse)

2. Les RPC streaming serveur permettent l’échange plus complexe de messages au sein d’un appel RPC unique. Le client émet d’abord une demande au serveur. Le serveur répond par un flux (Stream) comprenant une suite de messages plus large (commande de messages efficace au sein d’un appel RPC unique). Le client lit ce flux jusqu’à la fin des messages.

Exemple : rpc LotsOfReplies (HelloRequest) renvoie (stream HelloResponse)

3. Les RPC streaming client inversent le processus : le client écrit une suite de messages et l’envoie au serveur via un flux (Stream). Une fois que le client a écrit tous les messages, il attend que le serveur les lise et lui renvoie la réponse. La commande de message passe ici aussi par un appel RPC unique.

Exemple : rpc LotsOfGreetings (stream HelloRequest) renvoie (HelloResponse)

4. Les RPC streaming bidirectionnel sont la forme de communication la plus complexe. En effet, les deux côtés envoient un flux de messages. Ces deux flux de données sont indépendants l’un de l’autre, de sorte que le client et le serveur peuvent lire et écrire dans l’ordre qu’ils souhaitent : ainsi, le serveur peut attendre de recevoir tous les messages du client avant d’écrire ses réponses. Mais il peut aussi alterner la lecture d’un message avec l’écriture d’un message. Une autre combinaison de procédés de lecture et d’écriture est également possible.

Exemple : rpc BidiHello (stream HelloRequest) renvoie (stream HelloResponse)

Les variantes 2 à 4 établissent, au moyen de requêtes imbriquées, un multiplexage particulièrement performant, permettant le regroupement de plusieurs signaux sur une même connexion TCP, ainsi que leur transfert simultané sur le réseau. Performant, le protocole HTTP/2 prévient les blocages du trafic de données.

Les avantages et inconvénients de gRPC

Le gRPC présente de nombreux avantages : cette technologie est relativement simple à mettre en œuvre, dans la mesure où elle utilise un IDL simple et très facile d’utilisation pour la création des fichiers .proto. De cette manière, même des programmes anciens peuvent être facilement complétés par une interface gRPC performante et il est ainsi possible de transférer beaucoup plus rapidement des fichiers volumineux.

Par ailleurs, le gRPC a fait l’objet de nombreux tests et est hautement évolutif, ce qui lui permet de mener à bien les communications les plus complexes et exhaustives, au sein d’architectures client/serveur connectées à l’échelle internationale par exemple. HTTP/2 augmente ses performances, entre autres, grâce à ses capacités de multiplexage et de streaming bidirectionnel. Des compressions d’en-têtes sont également possibles lorsque le volume de données des requêtes et réponses doit être significativement réduit dans le réseau.

La structure multi-couches et fortement normalisée du framework gRPC permet de réduire les efforts de programmation. De cette manière, les développeurs peuvent se concentrer en priorité sur l’implémentation des méthodes. En cas de besoin, les programmeurs et développeurs de systèmes profitent du libre accès au code source et peuvent procéder eux-mêmes à des ajustements.

Les Protocol Buffers et les compilateurs Protobuf correspondants permettent par ailleurs une communication sans limite : les divers systèmes d’exploitation, les composants variés des architectures client/serveur et les différents langages de programmation ne font plus obstacle à la communication. Ainsi, un logiciel écrit en C peut communiquer avec le logiciel Java. Des compilateurs Protobuf sont désormais disponibles pour de nombreux autres langages, par exemple pour C#, C++, Go, Objective-C, Java, Python, Node.js, Android Java, Swift, Ruby et PHP.

La flexibilité de gRPC présente également un gros avantage : il peut par exemple être utilisé de la même manière pour l’échange de données de microservices ou le partage de données d’applications mobiles avec des serveurs. Autre point positif : le protocole permet l’implémentation de technologies de sécurité modernes. Le gRPC dispose ainsi d’une fonction d’authentification intégrée et promeut l’utilisation de SSL/TLS pour l’authentification et le cryptage des échanges.

Parmi les points faibles de gRPC, on peut noter que : le test des interfaces gRPC doit faire l’objet d’améliorations sur la base de l’état actuel de développement. Les messages gRPC codés avec protobuf ne peuvent pas être lus par des humains. Lors de l’analyse du trafic de données et, notamment, lors de la recherche d’erreurs et des opérations de dépannage (débogage), des instances supplémentaires doivent donc être utilisées pour retranscrire le code sous une forme compréhensible et pour localiser les sources d’erreurs. D’autres inconvénients résultent de la mise en réseau d’architectures client/serveur distribuées. Le gRPC connecte des ordinateurs à distance et est donc plus vulnérable que des systèmes locaux. Il dépend de l’accès à un réseau stable et performant. Les réseaux, le trafic de données, les protocoles de transmission ainsi que le client et le serveur ne doivent présenter aucun point d’attaque susceptible d’intéresser les pirates informatiques. Un autre inconvénient est que le gRPC ne prend pas en charge la multidiffusion.

Comparaison entre gRPC et REST

De par ses nombreuses propriétés positives, le gRPC s’impose comme une solution alternative concurrentielle au REST (Representational State Transfer). Ce dernier est particulièrement adapté à l’exécution de services simples, tandis que le gRPC déploie au mieux ses capacités au sein d’interfaces (API) et de services plus complexes. REST utilise généralement le format de données JSON, pour l’échange de données entre les applications. Il opère en mode texte et exploite ainsi les ressources du réseau.

Le gRPC, à l’inverse, peut organiser un flux de données sensiblement plus compact grâce aux Protocol Buffers et HTTP/2. De cette manière, les besoins en mémoire par sérialisation et binarisation des données sont réduits de près de 70 % par rapport à JSON. Le streaming bidirectionnel assure également, par rapport à REST, le fonctionnement sans blocage de l’échange de données pour des performances et une vitesse d’exécution grandement améliorées.

À l’heure actuelle, la collaboration avec des applications web gagnerait à être améliorée, car ces dernières ne sont souvent pas optimisées pour l’utilisation de Protocol Buffers, l’approche « le contrat d’abord » typique de gRPC, ainsi que les Contract First API du framework gRPC. Un inconvénient du travail avec des applications web est qu’aucun service gRPC n’est encore accessible directement depuis un navigateur. Ce n’est pas un problème avec REST, puisque le protocole HTTP classique est pris en charge par tous les navigateurs, contrairement au protocole HTTP/2 plus moderne. Toutefois, cette lacune peut être surmontée au prix d’un effort raisonnable, de sorte que le même service peut être utilisé pour une application Web et une application mobile. Une option dans ce domaine est le gRPC web. Les développeurs du gRPC travaillent sur d’autres solutions pour faciliter au maximum la compatibilité du gRPC avec les outils basés sur le web.

Dans quels cas le gRPC est-il utilisé ?

Le gRPC est plus particulièrement utilisé pour assurer une communication inter-processus efficace au sein d’architectures client-serveur distribuées, exigeant une faible latence et un débit de transmission élevé de données et de messages. Entre et au sein des centres de données distants, le gRPC est souvent utilisé pour interconnecter des services ou des microservices. Comme les outils du gRPC prennent en charge la plupart des langages de développement courants, ils sont souvent utilisés dans des environnements multilingues.

La vitesse, l’efficacité et le multilinguisme favorisent l’utilisation du gRPC avec les outils mobiles et pour la communication entre applications. Le gRPC régule en outre la dernière phase du traitement des données distribuées en connectant les appareils, les applications mobiles et les navigateurs avec les services backend.

Performant, le streaming via HTTP/2 prédestine le gRPC à la communication point à point en temps réel. L’internet des objets (technologies de maison intelligente) bénéficie de procédés sobres en ressources, car il se concentre de plus en plus sur la communication de clients à faibles ressources. De par ses nombreux avantages en matière de performance et sa simplicité de développement, cette technologie de communication pourrait devenir le leader de la communication en nuage. Cela relativiserait la domination actuelle de REST. Actuellement, le gRPC est également utilisé comme solution alternative au XML (Extensible Markup Language).

Note

XML est un format fréquemment utilisé pour l’échange de données et le stockage structuré d’informations.