Vous utilisez quel protocole de communication entre vos microservices ?
je pense que des API RESTful et des retors en JSON est probablement ce qu'il y a de plus commun.
Entre les microsservices? C’est ultra lent ce protocole
je vois ca beaucoup en pratique. Probablement parceque c'est facil a debugger. En tout cas pour les communications synchrones.
J'imagine que quand les volumes deviennent plus important et que tu sort des phases de developpement les gens le reconfigure en BSON ou protobuf pour l'echange de donnee.
J'imagine que il y a des cas ou tu peux vivre avec des communications asynchrone et donc tu fais certainement deux POST, une pour la requete et une pour la reponse.
Il faut voir que tu peux avoir un paquet de microservices qui peuvent communiquer entre eux si ton appel passe par 4 microservice qui communique tous entre eux par rest je dis pas le temps de réponse 😹
Au finale je suis même pas sur que dans ce cas là ça soit viable autant partir sur du monolithique
com.e d'hab, placer correctement les frontieres des modules dst toujours important pour minimiser les communications entre modules.
Ta des technos mis au points justement pour que les microservices communique le plus rapidement possible entre eux, perso j'ai utilisé azure service fabric mais ç& rend dépendant de leur cloud, je crois aws a un équivalent.
Il y a RabbitMq ça parait bien chiant à mettre en place et il semble consommé pas mal de ressource.
GRPC semble pas mal.
J'aimerai bien avoir des retours sur les différentes technos.
Techniquement REST c'est un protocole haut niveau, tu peux utiliser ce que tu veux derrière pour transporter tes données, t'es pas obligé de faire du HTTP / JSON. Donc je pense pas que c'est fondamentalement plus lent que RPC ou autre.
Pour moi les deux ont des utilisations différentes, REST c'est plus un protocole centré sur la manipulation de données, ça donne un très bon moyen d'organiser l'accès à tes données de manière claire et bien découpée. RPC c'est plus pour effectuer des actions, appeler des procédures à distances ( ) mais pas trop pour juste accéder à de la donnée (genre si tous tes endpoints c'est des get / set vaut mieux partir sur du REST).
Je parle de communication entre les microservices, si ton point d’entrée c’est une rest api ok, mais pour le reste c’est pas une bonne idée en tout cas j’ai jamais vu une telle utilisation de rest.
Pourquoi ? Pour tes microservices qui gèrent l'accès à la BDD c'est quand même très adapté je trouve.
Je me souviens que j'avais regardé cette vidéo qui parlait un peu de comment Netflix gère ça : https://www.youtube.com/watch?v=CZ3wIuvmHeM
Par contre j'ai oublié un peu les détails, donc je sais plus comment les microservices communiquent entre eux chez eux.
Disons que j'ai commencé à coder un serveur de jeu vidéo j'ai bien avancé, sauf que j'ai fais du monolithique et que c'est pas forcément une bonne idée, à terme j'aimerai bien transformer ça en microservices, mais faut pas que j'attendent trop sinon ça va être de plus en plus compliqué la transition.
Donc j'ai surtout une problématique de temps de réponse dans mon cas, j'utilise même des websockets pour communiquer entre mon jeu et mon serveur.
Sinon une petite comparaison entre grpc et rest
https://medium.com/@EmperorRXF/evaluating-performance-of-rest-vs-grpc-1b8bdf0b22da#:~:text=gRPC%20is%20roughly%207%20times,of%20HTTP%2F2%20by%20gRPC.
gRPC is roughly 7 times faster than REST when receiving data & roughly 10 times faster than REST when sending data for this specific payload. This is mainly due to the tight packing of the Protocol Buffers and the use of HTTP/2 by gRPC.
Comme j'ai dit tu peux faire du REST avec HTTP/2 + protobuff aussi, ça sera plus rapide que du REST avec JSON (qu'il semble avoir utilisé pour tester, en lisant en diagonale).
Je pense pas que REST soit fondamentalement plus lent que RPC, ça dépend surtout du protocole que tu utilises pour le transfert de données.
Déjà je crois il y a pas les mêmes possibilités entre les 2 et grpc est développer dans un soucis de performance , donc je pense que même si tu passe ton api rest en http2 avec protobuf chose qui ne doit pas être trivial, je ne suis même pas sur que les perfs seront les mêmes.
Non effectivement RPC et REST n'ont pas exactement le même but, j'ai essayé de l'expliquer un peu dans mon premier message mais je suis sûr qu'il doit y avoir des explications détaillées sur internet.
Là tu compares une bibliothèque avec un protocole, je te dis que fondamentalement RPC est pas plus rapide que REST, mais gRPC est sans doute plus rapide que plein de bibliothèques pour faire du REST oui, mais c'est un autre sujet. Mais je pense qu'il doit bien y avoir des bibliothèques REST centrées sur les perfs, après j'ai pas cherché plus que ça mais t'as déjà quelques résultats en cherchant REST + protobuff sur Google.
Dans tous les cas une API RPC est pas forcément plus adaptée qu'une API REST, pour moi si la seule raison que t'as de partir sur gRPC c'est parce que c'est une bibliothèque rapide alors tu fais un mauvais choix, il faut aussi se demander si RPC est un bon protocole pour l'API que tu veux designer. Forcer son architecture sur un modèle sous prétexte que tu connais une bonne bibliothèque c'est pas la meilleure des idées.
L'optimization de comm c'est toujours pareil quelquesoit la technologie qu'il y a en dessous. Ca n'a pas change depuis 40 ans.
1/ la comm la moins cher est celle que tu ne fais pas. C'est con a dire, mais tu serais etonne du nombre de code qui font des comms dont ils n'ont pas besoin, ou qui mettent plus d'information dans la comm qui n'est necessaire.
2/ Une comm commence par l'etablissement d'un canal de communication, que ca soit une connexion tcp, udp, http, whatever, il va falloir etablir la comm.udp c'est tres rapide (mais bon udp), tcp, tu as le 3 way handshake, ssh c'est horrible parcequ'il faut negocier la crypto. Si tu peux garder le canal ouvert, c'est probablement une bonne chose (et la raison pourlaquelle les gens aiment http2 je pense).
3/ Il y a une question de formation du message, certaines representations sont juste plus cher que d'autre, JSON requiert une serialization du message en ascii et ca coute cher, BSON c'est mieux, mais ca demande quand meme d'encoder des informations de type. Protobuf retire le besoin de mettre les types dans le paquet parceque la structure des messages est standardise comme une serialization binaire des objets. Note que tu peux obtenir des choses comme ca en structurant ton JSON de facon plus intelligente, par exemple en virant les dictionnaire et en les remplacant par des tableaux quand c'est possible. Naturellement un protocole qui sait exactement ce qu'il attend sera toujours plus rapide qu'un protocole qui a besoin de decoder ce que dit le message. La meilleure facon de reduire les couts de formation des messages est d'ecrire ton application pour vivre dans des donnees pre formate pour les echanges reseaux; c'est assez typique dans les applications data-flow. A peu de chose pres, tout le temps passer a encoder va etre passer a nouveau a decoder.
4/ Il faut passer du message a ce qui est envoye par la carte reseau. Il y a souvent une conversion de format qui est faite pour faire du zip, de la crypto, des check sum et cie. Et il y a les copies dans la carte reseau. La encore, si tu peux vivre directement dans le buffer de ta carte reseau ou avec du DMA avec la carte reseau, la vie ira mieux Mais il y a aussi une question de degager le zip si tu envoye des donnees binaires pas super compressible, voir de degager la crypto si tu as une assurance de la securite du canal de communication. (Deux VMs sur ton hote qui ne sert qu'a une seule application, ptet pas besoin de crypto). De plus en plus les boites de streaming shunte la pile TCP de linux et construisent les paquet en user-space: Comme tous les paquets sont forme pareil, ca sert a rien de traverser la stack TCP du noyaux a chaque paquet.
5/ il y a la communication en elle meme. C'est la que les questions de placements des services deviennent important. Si tu as des services qui communiquent plus entre eux, tu veux les mettre sur le meme hote ou dans le meme cluster. Note que si les deux services sont sur le meme hote, tu pourrait faire de la memeoire partage au lieu de traverser la stack reseau. Si tu es sur un reseau IB, tu peux directement utiliser le protocole IB au lieu de faire de l'IP. Voir tu peux faire du RDMA pour des applications plus couple.
6/ Finalement, il y a le comportement de l'application en elle meme. Si tu communique de facon synchrone ca veut dire que tu as des threads (ou des process, ou des user-threads) qui peuvent atetndre potentiellement. La question devient qui fait le dispatching du reseau, Si tu as un thread qui ecrit sur un socket, ca veut dire qu'il attend pour la reponse. Et il te faut plein de thread et ca coute cher en contexte d'execution ce qui fait que tu ne peux probablement pas avoir trop de communication/computation overlap. Et c'est le systeme d'exploitation qui fait le dispatching. Ca veut dire plein de socket TCP ouverte ce qui peut surcharger l'equipement reseau. Ou alors tu as une strcuture ou tous les messages sont indistinguable et arrive au meme endroit (c'est ce que tu veux dans les applications asynchrone), du coup l'application fait le dispatching des messages, et il faut s'assurer que le dispatcher ne devient pas bottleneck.
Ah ouais, bypasser la stack TCP du kernel c'est un terrain dans lequel je me suis encore jamais aventuré
Moi non plus, je n'ai jamais eu besoin d'un truc comme ca! ahah!
Mais c'est classique de configurer les clusters MPI ou les cluster hadoop pour tourner directement sur infiniband plutot que sur tcp/ip/infiniband. Le gain de perf (bande passante et latence) est monstrueux. En particulier parceque tu DMA et RDMA. Ou encore de bypasser la stack tcp/ip en utilisant des socket unix et de la memoire partage dans les cas ou les process tournent sur la meme machine. Ca pour le coup, c'est super standard.
Note que tous les problemes de perfs sont fondamentalement resolu de la meme facon. Il faut comprendre comment tes appels de haut niveau sont implementes en terme bit sur un canal ou qui traverse des transistors. Il faut comprender la pile entiere (algo, application, middleware, os, metal) pour voir qu'est ce qui coute cher et qui pourrait etre fait autrement. Apres tu te retrousse les manches et tu fais ca.
Et dans la plupart des cas quand tu regardes le probleme en entier, les problemes de perfs disparaissent avec un changement trivial. Le nombre de cas "c'est pas le bon algo", ou "pourquoi tu ecris dans un fichier pour le relire trois lignes plus loin", "ou pourquoi tu serialise tout dans un objet JSON a chaque ligne de ton code", ou "pourquoi tu implementes matrix multiply au lieu d'appeller la lib qui va bien".
Ca fait en gros 15 ans que je fais de la performance. Et des problemes externes qu'on m'a amener, je pense que j'ai du en voir qu'une dizaine qui etaient des problemes non triviaux. (Apres, j'ai mes problemes aussi, mais je parles de cas de gens qui viennent me voir avec un probleme de perf.)
Mon favori: "pourquoi tu ecris ta methode numerique en python sans lib? et pourquoi a chaque operation tu retransformes tous tes floats en string? Tu veux pas reecrire ta mega boucle de calcul numerique en C? Tu te rends compte que si tu inverses ces deux boucles, tu gagnes un ordre de grandeur sur le nombre de collision qu'il faut tester?" Le mec m'envoye le code, je le forward a un etudiant en master en lui disant, reecris ca en C et fait attention a l'ordre des boucles. Le lendemain, le code est passe de 4 jours sur 30 machines a 8 coeurs chacune a 0.3 secondes sur un laptop. VICTORY!
Ca m'étonnerais pas que ça soit fait sur des solution comme Azure Service Fabric.
Perso je cherche une solution performante et simple à installer, je vais pas tweaké du api rest pour essayer d'atteindre les perf de grpc.
Mon but est la communication entre les services avec de bon perf j'ai vu que grpc convenait bien à ce genre de scénario.
j'étais tombé sur une expérience sympa :
https://zestedesavoir.comm/billets/3598/jaime-ma-stack/
Sinon il y a rabbitmq mais ça à l'air bien chiant à mettre en place et en lui même je crois qu'il lui faut son propre container.
Après j'ai jamais vu d'exemple de communication entre service avec api rest, souvent le point d'entrée c'est une api rest mais derrière la communication entre les services passent par d'autre protocole.
[20:49:08] <godrik>
Mon favori: "pourquoi tu ecris ta methode numerique en python sans lib? et pourquoi a chaque operation tu retransformes tous tes floats en string? Tu veux pas reecrire ta mega boucle de calcul numerique en C? Tu te rends compte que si tu inverses ces deux boucles, tu gagnes un ordre de grandeur sur le nombre de collision qu'il faut tester?" Le mec m'envoye le code, je le forward a un etudiant en master en lui disant, reecris ca en C et fait attention a l'ordre des boucles. Le lendemain, le code est passe de 4 jours sur 30 machines a 8 coeurs chacune a 0.3 secondes sur un laptop. VICTORY!
Ah quand même
J'aime bien aussi ceux qui cherchent à optimiser avant de mesurer, partent du principe qu'un algo O(1) sera forcément plus rapide qu'un algo O(n) (ou autre), et au final se retrouvent à passer du temps pour avoir quelque chose de plus lent parce dans leur cas d'utilisation l'algo avec une complexité plus basse n'est au final pas plus rapide.
boucif, je sais pas si j'étais très clair mais j'ai pas dis que gRPC était un mauvais choix, juste que ta raison de faire ce choix n'était pas la meilleure.
Après dans tous les cas t'as pas forcément besoin de faire les meilleurs choix pour avoir un logiciel qui fonctionne, et c'est vrai que pour un projet perso des fois vaut mieux privilégier la simplicité en utilisant une bonne bibliothèque qui facilite beaucoup les choses même si ça colle pas parfaitement avec les besoins du logiciel.
À la base je réagissais surtout sur le "REST c'est plus lent que RPC", qui n'est pas vrai.
En quoi c’est pas la meilleure, j’essayais de voir quel sont les différentes possibilités, peut-être qu’il y en a que je ne connais pas, par contre ça m’a jamais traversé l’esprit d’utiliser rest parce qu’avec les technos que j’utilise ça serait sûrement du rest api et c’est lent, après rest en lui même sans passer par json et en http2 c’est peut-être bien mais je ne sais pas comment l’implementer, donc inutile.