Grigory Petrov: Arbeiten mit einem Netzwerk in Ruby

Am 28. September wird Grigory Petrov auf der Evrone RubyRussia DevRel-Konferenz darüber sprechen, wie Microservices kommunizieren. Im heutigen Interview sprach Ivan Solovyov mit Grigory über das Thema seiner bevorstehenden Rede und nicht nur darüber.

Bild

Erzähl uns von dir, was machst du bei Evrone?

Ich bin in Entwicklerbeziehungen involviert - dies ist etwas zwischen DevRel und Technology Evangelist, einem Entwickler, der auf Konferenzen sprechen kann. Arbeiten Sie wie Robin Hood: Kommunizieren Sie mit Entwicklungsteams im Unternehmen, sammeln Sie verschiedene interessante Dinge und sprechen Sie auf Konferenzen darüber. Ruby Russia wird eine der ersten Konferenzen sein, auf denen ich im Namen des Unternehmens sprechen werde.

Ich kenne Sie als einen der Organisatoren verschiedener Python-Konferenzen. Sag mir, wie du in die Welt von Ruby gekommen bist?

Ich habe die Welt von Ruby nie verlassen. Eine meiner ersten Vorlesungen war Python vs Ruby. Als ich vor vielen Jahren in C ++ schrieb, brauchte ich Automatisierungsmechanismen auf hoher Ebene für alle Tests und Dokumentationserstellungen. Dann schrieb ich in Python und Ruby und ein bisschen in PHP. Ich suchte nach den besten Möglichkeiten, um die Probleme zu lösen, die ich hatte.

Wie viel wird Ihr Bericht von Entwicklungsteams im Unternehmen ausgeliehen? Ich weiß, dass Sie in vielen Sprachen geschrieben haben: Ruby, Python, PHP, TypeScript, JavaScript, C ++ und nicht nur.

Der Bericht befasst sich mit der Kommunikation von Mikrodiensten untereinander über das Netzwerk, den dafür verwendeten Protokollen und den aufkommenden Schwierigkeiten. Tatsächlich habe ich eine lange Beziehung zum Raster. Ich habe Radmin gemacht, dies ist ein Netzwerk-Tool zur Fernsteuerung. Das NPTV-Projekt (in dem ich auch an DevRel gearbeitet habe) ist ein interaktives Fernsehen, das das Netz aktiv nutzt und auf Ruby steuert. Voximplant (wo ich wieder DevRel studiert habe) ist eine programmierbare Telefonie, bei der ich VoIP kennengelernt habe. Das Gitter ist sehr nah an mir. Ich könnte aufgrund meiner Erfahrungen einen Bericht erstellen, aber auf diese Weise würde ich den Gästen der Konferenz nicht den maximalen Wert bieten, aber ich möchte den maximalen Nutzen daraus ziehen. Während der ersten Erstellung des Berichts habe ich mehrere Evrone-Teams interviewt. Das Unternehmen beschäftigt sich mit der kundenspezifischen Entwicklung komplexer und qualitativ hochwertiger Software. Viele Teams arbeiten an verschiedenen Projekten. Wir haben bei Zoom angerufen und uns eine Stunde oder länger unterhalten. Sie diskutierten, was und wie sie tun, welche Schwierigkeiten, welche Stapel sie verwenden. In meinem Bericht geht es zur Hälfte um das Grid, die Netzwerkprotokolle, die Komplexität und die Anwendung sowie zur Hälfte darum, wie es in Ruby von verschiedenen Teams verwendet wird.

Sie haben viel Kommunikation mit Entwicklern. Wie spezifisch ist Ihrer Meinung nach die Arbeit mit einem Netzwerk in Ruby?

Das Netzwerk besteht aus mehreren Teilen. Zunächst die Arbeit der Programmiersprache und ihres Ökosystems direkt mit über das Netzwerk übertragenen Bytes. Der Netzwerkstapel der untersten Ebene. Zum Beispiel verwenden derselbe JS und Node libuv , ein asynchrones Modell. Es gibt einen Hauptstrom, und Sie arbeiten schließlich mit dem Netzwerk. Sie haben Coroutinen dafür. Sie machen viele Erwartungen, Sie warten, um die Daten zu erhalten, Sie warten, bis die Daten gesendet werden. Dieser einzelne Thread bietet Tausende und Zehntausende von Abfragen pro Sekunde.

Auf dieser Grundlage werden Frameworks entwickelt, was auch immer sie sind. Zum Beispiel hat JS keine ernsthaften Rahmenbedingungen für die Arbeit mit dem Raster (zu denen Sie ihm gratulieren können!). Mit Ausnahme von express.js, das kaum ein vollwertiges Framework ist. Python wechselte zu einem ähnlichen Modell, und das beliebteste Django-Framework blieb beim Vorgängermodell. Jetzt gibt es eine Art Zwietracht - ein synchrones Framework, das versucht, sich durch Blockieren von Threads zu verbreiten, Prozesse mit einer überhängenden GIL und nebenbei einige neue Dinge, die versuchen, an einem asynchronen Modell zu arbeiten, zum Beispiel Django-Kanäle. Ruby befindet sich immer noch im synchronen Modell und wird von Prozessen weitergegeben. Daher hier das entsprechende Ökosystem, Ansätze und sehr starke Positionen von Rails.

Was ist die Kraft von Ruby? Zunächst in DSL, domänenspezifische Sprache. Wenn wir über das Gitter sprechen, spielt Ruby am besten auf dem Gebiet, auf dem es am stärksten ist. Wenn wir GraphQL verwenden, bedeutet dies, dass Bibliotheken für die Verwendung von GraphQL überall sind. In Ruby verwenden sie eine sehr gute DSL-Syntax, um das Schema zu definieren. Und die Integration zwischen dieser DSL-Syntax und der DSL-ORM-Syntax in ActiveRecord. Genau das können wir von Ruby erwarten. Gleichzeitig werden wir keine asynchronen Operationen haben (warten), wir werden durch die Prozesse skaliert und wir werden die entsprechenden Serveranforderungen haben.

In Ihrem Bericht wurden mehrere Interaktionsprotokolle angegeben. Dieselbe JSON: API und so weiter. Wie sehen Sie die weitere Entwicklung? Werden wir alle in GraphQL einsteigen?

Eine sehr resonante Frage. Meiner Meinung nach begann es damit, dass das Gitter langsam ist. Die Anwendungen am Anfang sind einfach. In der Regel verwenden alle Anwendungen, sowohl Ruby als auch Python und Node, reguläre HTTP-Endpunkte für die Kommunikation. Im Inneren verwenden sie eine Art Nutzlast. Früher XML, jetzt JSON. In den ersten Monaten oder Jahren geht es ihnen gut, als hätten sie Glück. Als nächstes beginnt das Unternehmen, komplexe Fragen zu stellen. Beispielsweise müssen Sie einige Benutzer abrufen und für jeden Benutzer eine Liste der Unternehmen abrufen, in denen er arbeitet. Hier tritt das Problem auf: Wenn Sie nur den Endpunkt verwenden, sind es mehrere zehn oder Hunderte von Anforderungen, und das Raster ist gemächlich: Anforderung, Antwort, verlorene Pakete. Es wird ungeheuer langsam sein und viele Daten müssen über das Netzwerk übertragen werden. 100 mal mehr als die erforderlichen Daten. Unser System bricht zusammen, da große Geschäftsautomatisierungssysteme unter solchen Anforderungen zusammenbrechen, die in 10 Jahren zu Monstern werden, bei denen Minuten und Stunden eine komplizierte Frage über die Benutzeroberfläche sein können. Während dieser ganzen Zeit verarbeitet die Datenbank im Backend eine Reihe identischer Anforderungen, und eine Reihe identischer Anforderungen wird im gesamten Netzwerk verfolgt. Wir versuchen es auf verschiedene Arten zu lösen.

Geben Sie echte Beispiele für solche Probleme?

Facebook wurde besonders ausgezeichnet, sie haben dieses Problem sehr akut: Es gibt viele Daten, zu denen sie gerne komplexe Abfragen stellen. Zum Beispiel: Zeigen Sie mir diejenigen, die diesen Beitrag kommentiert haben, und ihre Freunde. Um nicht Millionen von Anfragen zu stellen, verwendet Facebook verschiedene Optionen. Zum Beispiel FQL, Facebook Query Language. Nachdem sie all ihr Fachwissen gesammelt haben, haben sie GraphQL erstellt - eine Sache, mit der Sie SQL-ähnliche Abfragen auf dem Client durchführen können. Dies ist jedoch nicht SQL, da wir nicht an Datenbanken angehängt werden können, sondern eine Abfrage in Bezug auf die Backend-API. Sie senden eine Anfrage und erhalten eine Antwort (oder wie es geht).

Das zweite große Problem ist, was zu tun ist, wenn wir viele Daten vom Backend erhalten möchten. Zum Beispiel fünftausend Benutzer oder ein Login in 10 MB. Es ist beängstigend, alles mit einer http-Anfrage-Antwort zu machen. Denn wenn das Netz zusammenbricht, muss die Anforderung vollständig wiederholt werden, und dies kann für immer dauern. Zurück zu Facebook: Sie haben GraphQL gemacht, eine Krücke über dem Gitter. Und dann haben andere Leute HTTP / 2 gemacht, was das Grid-Problem löst. HTTP / 2 stellt eine asynchrone Verbindung her, innerhalb derer wir viele kleine Anfragen stellen können. HTTP / 2 hat Probleme mit GraphQL, wenn der GraphQL-Server nicht viel Magie hat, um die Anzahl der Abfragen an die Datenbank im Backend zu optimieren. Und im Vortrag werden wir darüber sprechen, was Ruby für diese Magie bietet. Mit HTTP / 2 wird GraphQL möglicherweise nicht benötigt. Wir können 100 HTTP / 2-Anforderungen an unseren Endpunkt senden, und aus Sicht der Bytes ist dies kein größerer Aufwand als bei Verwendung von GraphQL. Google Protocol Buffers und gRPC nähern sich diesem Problem ab dem dritten Ende. Sie verwenden binäre Transportprotokolle, hauptsächlich HTTP / 2, sie bieten ein bestimmtes Schema für API. Hier konkurrieren sie mit dem üblichen REST.

In der Praxis sitzt und schreibt der Programmierer Vasya in den meisten Unternehmen, die JSON verwenden, diesen JSON mit seinen Händen. Sechs Monate später erfährt Vasya, dass Datum und Uhrzeit auf hundert verschiedene Arten übertragen werden können. Horror beginnt! Aber wenn gute Entwickler im Unternehmen sitzen, schreiben sie nicht nur JSON, sondern verwenden eine Art Standard. Mit OpenAPI oder JSON Schema all diese interessanten Dinge, die mit gRPC konkurrieren. Dieser ganze moderne Zoo löst einige Probleme. Und was in Zukunft mit diesem Zoo passieren wird, kann ich überhaupt nicht vorhersagen. Aber ich lade Entwickler ein, dieses Thema zu diskutieren: Was erwartet uns im kommenden Jahr, 3, 5, 10 und wie ist die Disposition der Kräfte jetzt?

Lassen Sie uns über die Zukunft von Ruby als Programmiersprache sprechen.

Es ist schwer, die Zukunft vorherzusagen. Ich würde wirklich gerne gute Typen in Ruby sehen. Ruby 3 befindet sich jetzt in der Anfangsphase der Typimplementierung. Ich möchte, dass diese Syntax schön ist. Ich sah die Vorschläge, meine kahle Stelle stand ihnen gegenüber. Schreckliche, sehr ausführliche Syntax, die niemand verwenden wird.

Warum denkst du so?

Ich bin ein Amateur-Neurophysiologe. Das intuitive Denken, dass jeder gerne alle möglichen seltsamen Entscheidungen trifft. Wenn Sie zum Beispiel viele Briefe schreiben müssen, ist das schlecht. Diese Typen können mega-cool sein, aber aufgrund der Tatsache, dass Sie eineinhalb Mal mehr Code schreiben müssen, werden wir die Emotion "Ich will nicht" spüren. Und wir sind sehr empfindlich gegenüber unseren Emotionen, so dass niemand sie benutzen wird. Ich mag die Art und Weise, wie die Typen in Python und TypeScript übermittelt wurden: durch den Doppelpunkt. Dies ergibt einen minimalen Overhead. Wir haben einen Bezeichner geschrieben - geschaut. Ich weiß sicher, dass es eine Nummer geben wird, Sie müssen eine Falle stellen. Der Entwickler schreibt einen Doppelpunkt und das wars, die Falle ist installiert. Nach ein paar Wochen, wenn er versehentlich eine Liste oder Zeile dort passiert, funktioniert die Falle und spart dem Entwickler mehrere Stunden oder Wochen des Debuggens.

Was möchten Sie sonst noch in Ruby sehen?

In den letzten Jahren habe ich viel Asynchronität mit Coroutinen gesehen. Ich mag das wirklich, weil asynchroner Code mit Coroutinen leicht zu lesen ist. Es ist verständlich, ermöglicht es Ihnen, komplexe Dinge in einfache Syntax zu packen. Dies ist in der neuesten Python gut implementiert und in JavaScript gut implementiert. Ich würde wirklich gerne, dass Ruby so etwas mitbringt ... Eigentlich hat Ruby Ballaststoffe. Es wäre cool, so etwas wie Node hinzuzufügen, damit Sie asynchrone Ruby-Anwendungen mit Fasern oder anderen Grundelementen schreiben können. Und unter der Haube würde es selbst libuv oder andere Betriebssystemprimitive verwenden, um mit dem Grid zu arbeiten.

Oder es würde etwas in Strömen auslegen. Würde etwas verwenden, um alle diese Netzwerkanforderungen, Datenbankanforderungen und Dateisystemanforderungen wettbewerbsfähig zu erfüllen. Und ich würde Coroutine nur auf der Ebene kleiner Codeteile schreiben, die bei einer eingehenden Anforderung oder einem eingehenden Timer ausgeführt werden, dann Befehle ausgeben und auf deren Ausführung warten. Weiter unter der Haube viel Magie, all dies geschieht parallel, frisst ein riesiges Amazon-Auto zu 100% auf und hat Zehntausende von Anfragen pro Sekunde. Im Fall von Go Hunderttausende von Abfragen pro Sekunde.

Zurück zu den Typen. Dies wird wahrscheinlich die schrittweise Einführung von Typen sein, schrittweise Eingabe?

Gradual Typing ist ein Mega-Höhenflug, der zuerst zu Python hinzugefügt wurde. Wir haben es so gemacht, dass Typen ein wenig hinzugefügt werden können. Meiner Meinung nach ist ein ganzes Entwicklungsparadigma entstanden, als der Code am Anfang sehr schnell ohne Typen geschrieben wurde und wenn der Entwickler feststellt, dass sich ein Teil des Codes stabilisiert hat, beginnen Typen, diesen Teil des Codes zu ergänzen. Hier hat es sich stabilisiert und es ist notwendig, Fallen zu stellen, damit in Zukunft nichts an diesem stabilisierten Fall kaputt geht. Es wäre cool, wenn sie etwas Ähnliches für Ruby tun würden.

Welche Frage möchten Sie Yukihiro Matsumoto auf der Konferenz stellen?

Ich lerne seit 4 Jahren Japanisch und mein Japanisch reicht wahrscheinlich aus, um ihm „Danke“ zu sagen. Ich werde trainieren!

Wir sehen uns bei RubyRussia!

Registrieren Sie sich , die nächste Preiserhöhung wird nach dem 15. September erwartet, 700 Teilnehmer sind bereits bei uns.

Und traditionell dank der Unternehmen, die uns unterstützen:

Veranstalter - Evrone
Komplementärin - Toptal
Gold Partner - Gett
Silver Partners - JetBrains , Bookmate und Cashwagon
Bronze Partner - InSales

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


All Articles