Grigory Petrov: travailler avec un réseau à Ruby

Le 28 septembre, lors de la conférence Evrone RubyRussia DevRel, Grigory Petrov parlera de la façon dont les microservices communiquent. Dans l'interview d'aujourd'hui, Ivan Solovyov a parlé avec Grigory du sujet de son prochain discours et pas seulement à ce sujet.

image

Parlez-nous de vous, que faites-vous chez Evrone?

Je suis impliqué dans les relations avec les développeurs - c'est quelque chose entre DevRel et Technology Evangelist, un développeur qui peut parler lors de conférences. Travaillez comme Robin Hood: communiquez avec les équipes de développement au sein de l'entreprise, collectez diverses choses intéressantes de ce qu'elles font et parlez-en lors de conférences. Ruby Russia sera l'une des premières conférences où je parlerai au nom de l'entreprise.

Je vous connais comme l'un des organisateurs de diverses conférences Python. Dites-moi comment vous êtes arrivé dans le monde de Ruby?

Je n'ai jamais quitté le monde de Ruby. L'une de mes premières conférences a été Python vs Ruby. Il y a de nombreuses années, lorsque j'écrivais en C ++, j'avais besoin de mécanismes d'automatisation de haut niveau pour tout test, génération de documentation. Ensuite, j'ai écrit en Python et Ruby, et un peu en PHP. Je cherchais les meilleurs moyens de résoudre les problèmes que j'avais.

Combien votre rapport sera-t-il emprunté aux équipes de développement de l'entreprise? Je sais que vous avez écrit dans de nombreux langages: Ruby, Python, PHP, TypeScript, JavaScript, C ++ et pas seulement.

Le rapport portera sur la communication des microservices entre eux sur le réseau, les protocoles utilisés pour cela et les difficultés émergentes. En fait, j'ai une longue relation avec la grille. J'ai fait Radmin, c'est un outil réseau pour le contrôle à distance. Le projet NPTV (dans lequel j'ai également travaillé DevRel) est une télévision interactive qui utilise activement la grille et contrôle sur Ruby. Voximplant (où j'ai étudié à nouveau DevRel) est une téléphonie programmable où j'ai rencontré la VoIP. La grille est très proche de moi. Je pourrais faire un rapport basé sur mon expérience, mais de cette façon, je n'apporterais pas la valeur maximale aux invités de la conférence, mais je veux en profiter au maximum. Lors de la préparation initiale du rapport, j'ai interviewé plusieurs équipes Evrone. L'entreprise est engagée dans le développement personnalisé de logiciels complexes et de haute qualité, de nombreuses équipes travaillent sur différents projets. Nous avons appelé Zoom et avons parlé pendant une heure ou plus. Ils ont discuté de quoi et comment ils font, quelles difficultés, quelles piles ils utilisent. Mon rapport portera à moitié sur la grille, les protocoles réseau, la complexité et l'application, et à moitié sur la façon dont il est utilisé dans Ruby par différentes équipes.

Vous avez beaucoup de communication avec les développeurs. Dans quelle mesure pensez-vous que travailler avec un réseau en Ruby est spécifique?

Le réseau se compose de plusieurs parties. Tout d'abord, le travail du langage de programmation et de son écosystème directement avec des octets transmis sur le réseau. La pile réseau de niveau le plus bas. Par exemple, les mêmes JS et Node utilisent libuv , un modèle asynchrone. Il existe un flux principal et vous travaillez éventuellement avec le réseau. Vous avez des coroutines pour cela. Vous faites beaucoup d'attentes, vous faites une attente pour recevoir les données, vous faites l'attente pour que les données soient envoyées. Ce thread unique fournit des milliers et des dizaines de milliers de requêtes par seconde.

Sur cette base, des cadres sont développés, quels qu'ils soient. Par exemple, JS n'a pas de cadres sérieux pour travailler avec la grille (pour laquelle vous pouvez le féliciter!). À l'exception de express.js, qui n'est guère un cadre à part entière. Python est passé à un modèle similaire et le framework Django le plus populaire est resté sur le modèle précédent. Il y a maintenant une sorte de discorde - un framework synchrone qui essaie de se propager en bloquant les threads, les processus avec un GIL en surplomb, et sur le côté il y a de nouvelles choses qui essaient de travailler sur un modèle asynchrone, par exemple Django Channels. Ruby est toujours dans le modèle synchrone et propagé par les processus. Voici donc l'écosystème correspondant, les approches et les positions très fortes de Rails.

Quelle est la puissance de Ruby? Tout d'abord, en DSL, langage spécifique au domaine. Lorsque nous parlons de la grille, Ruby joue mieux dans le domaine où elle est la plus forte. Lorsque nous utilisons GraphQL, cela signifie que les bibliothèques pour utiliser GraphQL sont partout. Dans Ruby, ils utiliseront une très bonne syntaxe DSL pour définir le schéma. Et l'intégration entre ces syntaxe DSL et la syntaxe DSL ORM dans ActiveRecord. C'est exactement ce que nous pouvons attendre de Ruby. Dans le même temps, nous n'aurons aucune opération asynchrone (en attente), nous serons mis à l'échelle par les processus et nous aurons les exigences de serveur correspondantes.

Votre rapport mentionne plusieurs protocoles d'interaction. Le même JSON: API et ainsi de suite. De quelle manière voyez-vous le développement, allons-nous tous glisser dans GraphQL?

Une question très résonnante. À mon avis, cela a commencé avec le fait que la grille est lente. Les applications au début sont simples. En règle générale, toutes les applications, Ruby, Python et Node, utilisent des points de terminaison HTTP normaux pour la communication. À l'intérieur, ils utilisent une sorte de charge utile. Auparavant XML, maintenant JSON. Ils se portent bien pendant les premiers mois ou les premières années, comme s'ils avaient de la chance. Ensuite, l'entreprise commence à poser des questions complexes. Par exemple, vous devez obtenir certains utilisateurs et, pour chaque utilisateur, obtenir une liste des entreprises dans lesquelles il travaille. Ici, le problème se pose: si vous utilisez simplement un point de terminaison, il y aura alors plusieurs dizaines ou centaines de demandes, et la grille est tranquille: demande, réponse, paquets perdus. Ce sera monstrueusement lent et beaucoup de données devront être transmises sur le réseau. 100 fois plus que les données requises. Notre système s'effondre, car les grands systèmes d'automatisation des entreprises s'effondrent sous de telles demandes, qui en 10 ans deviennent des monstres, où les minutes, les heures peuvent être une question compliquée à partir de l'interface. Pendant tout ce temps, la base de données sur le backend travaillera sur un tas de requêtes identiques, et un tas de requêtes identiques se poursuivra sur le réseau. Nous essayons de le résoudre de différentes manières.

Donnez de vrais exemples de tels problèmes?

Facebook était particulièrement distingué, ils ont ce problème très aigu: il y a beaucoup de données sur lesquelles ils aiment faire des requêtes complexes. Par exemple: montrez-moi ceux qui ont commenté ce post et leurs amis. Afin de ne pas faire des millions de demandes, Facebook utilise différentes options. Par exemple, FQL, Facebook Query Language. Après avoir rassemblé toute leur expertise, ils ont créé GraphQL - une chose qui vous permet de faire des requêtes de type SQL sur le client. Mais ce n'est pas du SQL, car nous ne pouvons pas être attachés à des bases de données, mais une requête en termes d'API backend. Vous envoyez une demande et vous obtenez une réponse (ou comment ça se passe).

Le deuxième gros problème est de savoir quoi faire si nous voulons obtenir beaucoup de données du backend. Par exemple, cinq mille utilisateurs ou une connexion à 10 Mo. Il est effrayant de tout faire avec une seule requête-réponse http. Parce que si le maillage s'effondre, la demande devra être répétée dans son intégralité, et cela peut durer éternellement. De retour sur Facebook: ils ont fait GraphQL, une béquille sur la grille. Et puis d'autres personnes ont fait HTTP / 2, ce qui résout le problème de grille. HTTP / 2 établit une connexion asynchrone, au sein de laquelle nous pouvons faire de nombreuses petites demandes. HTTP / 2 combat GraphQL si le serveur GraphQL n'a pas beaucoup de magie pour optimiser le nombre de requêtes vers la base de données sur le backend. Et dans le discours, nous parlerons de ce que Ruby offre pour cette magie. Avec HTTP / 2, GraphQL peut ne pas être nécessaire. Nous pouvons faire 100 requêtes HTTP / 2 à notre point de terminaison, et du point de vue des octets, ce ne sera pas une surcharge plus importante que si nous utilisons GraphQL. Les tampons de protocole Google et gRPC abordent ce problème à partir de la troisième extrémité. Ils utilisent des protocoles de transport binaires, principalement HTTP / 2, ils offrent un certain schéma pour l'api. Ici, ils rivalisent avec le REST habituel.

En pratique, dans la plupart des entreprises qui utilisent JSON, le programmeur Vasya s'assoit et écrit ce JSON avec ses mains. Six mois plus tard, Vasya apprend que la date et l'heure peuvent être transmises de cent manières différentes. L'horreur commence! Mais si de bons développeurs siègent dans l'entreprise, ils écrivent non seulement JSON, mais utilisent une sorte de standard. En utilisant OpenAPI ou JSON Schema, toutes ces choses intéressantes qui rivalisent avec gRPC. Tout ce zoo moderne résout quelques problèmes exprimés. Et ce qui va arriver à ce zoo à l'avenir, je ne peux pas du tout le prévoir. Mais j'invite les développeurs à venir discuter de cette question: ce qui nous attend dans l'année à venir, 3, 5, 10 et quelle est la disposition des forces maintenant.

Parlons de l'avenir de Ruby en tant que langage de programmation?

Il est difficile de prédire l'avenir. J'aimerais vraiment voir de bons types en Ruby. Ruby 3 est maintenant au stade très initial de l'implémentation de type. J'aimerais que cette syntaxe soit belle. J'ai vu les propositions, ma calvitie s'est tenue à bout d'eux. Syntaxe affreuse et très verbeuse que personne n'utilisera.

Pourquoi le pensez-vous?

Je suis neurophysiologiste amateur. La pensée intuitive que tout le monde aime aime prendre toutes sortes de décisions étranges. Si, par exemple, vous avez besoin d'écrire beaucoup de lettres, c'est mauvais. Ces types peuvent être méga-cool, mais étant donné que vous devez écrire une fois et demie de code en plus, nous ressentirons l'émotion «Je ne veux pas». Et nous sommes très sensibles à nos émotions, donc personne ne l'utilisera. J'aime vraiment la façon dont les types ont été transmis en Python et TypeScript: à travers les deux points. Cela donne une surcharge minimale. Nous avons écrit un identifiant - regardé. Je sais pour sûr qu'il y en aura un certain nombre, il faut mettre un piège. Le développeur écrit deux points et c'est tout, le piège est installé. Après quelques semaines, lorsqu'il passe accidentellement une liste ou une ligne, le piège fonctionne et économise au développeur plusieurs heures ou semaines de débogage.

Qu'aimeriez-vous voir d'autre à Ruby?

Au cours des dernières années, j'ai vu beaucoup d'async avec des coroutines. J'aime vraiment cela parce que le code asynchrone avec les coroutines est facile à lire. Il est compréhensible, vous permet de caser des choses complexes dans une syntaxe simple. Ceci est bien implémenté dans le dernier Python et bien implémenté en JavaScript. J'aimerais vraiment que Ruby apporte quelque chose comme ça ... En fait, Ruby a des fibres. Il serait intéressant d'ajouter quelque chose comme Node pour pouvoir écrire des applications Ruby asynchrones en utilisant des fibres ou d'autres primitives. Et sous le capot, il utiliserait lui-même libuv ou d'autres primitives de système d'exploitation pour fonctionner avec la grille.

Ou il disposerait quelque chose en flux. Utiliserait quelque chose afin de répondre de manière compétitive à toutes ces demandes réseau, demandes de base de données, demandes de système de fichiers. Et je n'écrirais la coroutine qu'au niveau de petits morceaux de code qui sont exécutés sur une requête ou une minuterie entrante, puis je donnais des commandes et j'attendais leur exécution. Plus loin sous le capot, beaucoup de magie, tout cela se fait en parallèle, dévore à 100% une énorme voiture Amazon et a des dizaines de milliers de requêtes par seconde. Dans le cas de Go, des centaines de milliers de requêtes par seconde.

Revenons aux types. Ce sera probablement l'introduction progressive des types, Gradual Typing?

Gradual Typing est une méga montée en flèche qui a d'abord été ajoutée à Python. Nous l'avons fait pour que les types puissent être ajoutés un peu. À mon avis, tout un paradigme de développement est apparu lorsque, au début, le code est écrit très rapidement sans types, puis lorsque le développeur voit qu'une partie du code s'est stabilisée, les types commencent à s'ajouter à cette partie du code. C'est là qu'il s'est stabilisé et il est nécessaire de poser des pièges pour qu'à l'avenir rien ne soit brisé à propos de celui-ci stabilisé. Ce serait cool s'ils faisaient quelque chose de similaire pour Ruby.

Quelle question voulez-vous poser à Yukihiro Matsumoto lors de la conférence?

J'étudie le japonais depuis 4 ans, et mon japonais est probablement suffisant pour lui dire "merci". Je vais m'entraîner!

Rendez-vous à RubyRussia!

Inscrivez-vous , la prochaine augmentation de prix est attendue après le 15 septembre, 700 participants sont déjà parmi nous.

Et traditionnel grâce aux entreprises qui nous soutiennent:

Organisateur - Evrone
Associé commandité - Toptal
Partenaire Gold - Gett
Partenaires Silver - JetBrains , Bookmate et Cashwagon
Partenaire Bronze - InSales

Source: https://habr.com/ru/post/fr467029/


All Articles