Warum wir Java aufgegeben und Typescript ohne Server übernommen haben

Dieser Artikel ist nur ein Nachdruck des technischen Teils des persönlichen Blogs. Warum haben wir Java aufgegeben und Typescript ohne Server übernommen - Junks, GC kann nicht fegen-

Wie ich im Blog schrieb, gibt es aufgrund verschiedener Umstände auch zuerst eine englische Version. Ich habe das auch geschrieben, also verstehe bitte, dass es kein Diebstahl ist.

\ [Originalartikel ]: Warum wir Java durch Typescript für Serverless ersetzt haben in dev.to

Einführung

** serverlos ** ist heutzutage eine der heißesten Entwurfsmethoden, und vielleicht beginnen viele Entwickler, sie mehr oder weniger auf ihre Produkte anzuwenden.

Ich selbst bin völlig fasziniert von Serverlosigkeit und habe keine Lust, in die altmodische Welt der Verwaltung und des Betriebs von Servern und Middleware zurückzukehren.

Wenn Ihre Anwendung auf Skalierung und Verteilbarkeit ausgelegt ist, sind die Vorteile herkömmlicher Serveranwendungsfunktionen relativ gering, und die Nachteile des Wechsels zu serverlos sind nicht so groß. Wenn ich in letzter Zeit eine Beratung zum Thema Design habe, versuche ich immer, über Serverless zu sprechen.

Serverless unterscheidet sich übrigens stark von der vorhandenen Entwicklungsmethode. Daher ist es notwendig, das vorhandene Wissen zu erneuern und zu entwickeln, während der vorhandene Methoden- und Technologie-Stack überprüft wird. In Bezug auf die Überprüfung ** hängt die Sprache, die als Entwicklungsplattform verwendet werden soll **, natürlich vom Technologie-Stack ab, der überprüft werden muss.

Wie der Titel schon sagt, haben wir endlich ** TypeScript ** übernommen und entwickeln und warten es seit ungefähr anderthalb Jahren. Und jetzt, anderthalb Jahre später, ist es nur mein persönlicher Eindruck, aber TypeScript hat mehr getan, als wir erwartet hatten.

In diesem Artikel möchte ich erklären, was mit der zuvor verwendeten Sprache schief gelaufen ist und warum ich von der Umstellung auf TypeScript profitiert habe.

Warum ich Java aufgeben musste

Bevor wir darüber sprechen, warum wir TypeScript eingeführt haben, wollen wir zunächst darüber sprechen, warum wir Java, die sehr leistungsfähige Sprache, die wir zuvor verwendet haben, aufgeben mussten.


Wie ich bereits erwähnt habe, mag ich Java sehr. Die erste Sprache, die ich berührte, war Java. Ich habe JVM bis zu einem gewissen Grad studiert und bin ziemlich beeindruckt davon, wie die göttliche Laufzeit funktioniert. (Vielleicht ist der, den ich gemacht habe, Gott) Also, wie einige College-Studenten, ** Java ist Scheiße, Vermächtnis oder nutzlos, das werde ich in diesem Artikel nicht sagen. ** ** ** Auch mit solchen Kommentaren bin ich nicht sehr zufrieden. Es ist nur so, dass Java nicht wirklich in den serverlosen Mechanismus passte. Wir würden uns freuen, wenn Sie diesen Punkt verstehen könnten.

Warum ich Java aufgeben musste

Bevor wir darüber sprechen, warum wir TypeScript eingeführt haben, wollen wir zunächst darüber sprechen, warum wir Java, die sehr leistungsfähige Sprache, die wir zuvor verwendet haben, aufgeben mussten.

In unserem Dienst wurde die Serverseite ab dem Zeitpunkt der Einrichtung des Dienstes grundsätzlich nur in Java geschrieben. Natürlich hat Java bereits viele Vorteile, insbesondere

  • ** Plattformfrei **
  • ** Gut gemachte JIT-Kompilierung **
  • ** Yabai GC **
  • ** Gut strukturierte Grammatik **
  • ** Statische Eingabe **
  • ** Funktionsunterstützung (besonders heutzutage) **
  • ** Verschiedene Bibliotheken **
  • ** Zuverlässige Community ** (Entwickler, nicht Oracle)

Die Liste hat kein Ende.

Als ich jedoch mit dem Code auf AWS Lambda experimentierte, stellte ich fest, dass Java nicht sehr serverlos war.

Die Gründe sind wie folgt.

  • ** Der JVM-Startaufwand ist groß **
  • ** Bei Verwendung des Spring Frameworks wird es noch schlimmer **
  • ** Das endgültige Paketarchiv ist zu groß (groß ist über 100 MB) **
  • ** Mit zunehmender Anzahl von Funktionen wird es schwieriger, Anforderungen ohne Webframework zu bearbeiten **
  • ** Der Container läuft nur etwa 30 Minuten, sodass Sie Java wie G1GC und JIT nicht nutzen können **
  • ** Lambda läuft grundsätzlich auf Amazon Linux-Containern, die auf EC2 basieren, daher ist plattformfrei irrelevant. ** (kein Nachteil)

Alle oben genannten Punkte sind ziemlich ärgerlich, aber dieses Mal möchte ich etwas mehr über die Themen schreiben, die besonders ärgerlich waren.

Kaltstart ist ernst und mühsam

Das nervigste war der überwältigende ** Kaltstart-Overhead **. Vielleicht leiden auch viele Entwickler darunter. .. ..

Wir haben AWS Lambda als unsere Computerinfrastruktur verwendet, aber AWS Lambda startet jedes Mal einen neuen Container, wenn ein Benutzer dies anfordert.

Nach dem Start wird ** dieselbe Containerinstanz ** für eine Weile wiederverwendet **, aber beim ersten Start werden zusätzlich zur Java-Laufzeit der im Framework verwendete DI-Container und der Webcontainer alle ** verwendet Muss initialisiert werden **.

Außerdem kann ** ein Container nur eine Anfrage verarbeiten, nicht mehrere Anfragen **. (Auch wenn Sie Hunderte von Anfragethreads intern bündeln.)

Dies bedeutet, dass Lambda, wenn mehrere Benutzer gleichzeitig Anforderungen senden, zusätzlich zu dem laufenden Container einen weiteren Container starten muss. Normalerweise können wir nicht im Voraus vorhersagen, wie viele Anfragen zu welchem Zeitpunkt gleichzeitig eingehen werden. Mit anderen Worten, selbst wenn Sie einen Mechanismus erstellen, ist es nicht möglich, alle Lambdas im Voraus in den Hot-Standby-Modus zu versetzen.

Dies zwingt den Benutzer zwangsläufig dazu, einige Sekunden bis 10 Sekunden oder länger zu warten, was die Benutzerfreundlichkeit erheblich verringert.

Als wir feststellten, dass Kaltstart so schrecklich war, beschlossen wir, den in den letzten Jahren geschriebenen Technologie-Stack aufzugeben und eine andere Sprache zu wählen.

Warum ich mich für TypeScript entschieden habe

Es ist eine peinliche Geschichte, aber ehrlich gesagt habe ich mich nicht entschieden, alle von Lambda unterstützten Sprachen zu untersuchen und zu vergleichen. Aber um ehrlich zu sein, gab es in dieser Situation keine andere Option als TypeScript.

Zunächst ** habe ich die dynamisch eingegebene Sprache entfernt **. Wartung und Instandhaltung durch Entwickler mit unterschiedlichen Fähigkeiten über einen langen Zeitraum. Ich möchte die dynamische Eingabe nicht wirklich verwenden, da es sich um erweiterten Code handelt.

Daher waren ** Python ** und ** Ruby ** schon früh nicht mehr in den Optionen.

Bei ** C # ** und ** Go ** entwickeln die meisten Teams derzeit hauptsächlich Java. Wenn Sie also eine Sprache verwenden, die weit von der vorhandenen Sprache entfernt ist, ist es für neue Entwickler schwierig, Mitglied zu werden. Nach ** zu urteilen, wurde es diesmal zurückgestellt.

Natürlich weiß ich, dass diese beiden Hauptsprachen heutzutage viel Aufmerksamkeit erhalten, und insbesondere Golang erhöht allmählich seinen Anteil. Wir mussten die Entwicklung jedoch schnell auf serverlos umstellen, sodass wir angesichts unserer eigenen Nachholzeit darauf verzichten mussten.

Vorteile von TypeScript

Deshalb haben wir angefangen, TypeScript zu verwenden. Was sind die Vorteile von TypeScript?

  • ** Statische Eingabe **
  • ** Kleinpaketarchiv **
  • ** Fast 0 Sekunden Startaufwand **
  • ** Java- und JavaScript-Kenntnisse können wiederverwendet werden **
  • ** NodeJS-Bibliotheken und Communitys können verwendet werden **
  • ** Funktionale Programmierung ist einfacher als JavaScript **
  • ** Einfach zu zeichnender Code, strukturiert nach Klasse und Schnittstelle **

Es ist nicht notwendig darüber zu sprechen, inwieweit die statisch typisierte Sprache Vorteile für Projekte bringen kann, die über einen langen Zeitraum betrieben und entwickelt werden, daher werde ich sie hier nicht schreiben. Hier möchte ich hauptsächlich darüber schreiben, welche Punkte von TypeScript für die Entwicklung ohne Server bekannt sind. Die Vorteile der Verwendung von TypeScript außer der statischen Typisierung sind enorm.

Kleines Paket und kleiner Startaufwand

Ich denke, dies war wahrscheinlich das Wichtigste im Hinblick auf die Vorteile der Verwendung von TypeScript ohne Server. (Weil die anderen Vorzüge fast die Vorzüge von TypeScript selbst sind ...)

Wie bereits erwähnt, hat Java einen sehr großen Aufwand für das Starten des DI / Web-Containers, der von der JVM selbst und dem Framework verwendet wird. Aufgrund der Natur von Java weist AWS Lambda außerdem die folgenden Schwächen auf.

** Multithreading und das es umgebende Ökosystem **

Multithreading ist eine sehr leistungsstarke Funktion, und dank dieser Funktion haben wir viele Leistungsprobleme gelöst. Die JVM selbst nutzt standardmäßig auch Multithreading für die Speicherbereinigung und JIT-Kompilierung, um diese hervorragende Laufzeit zu erreichen. (Einzelheiten finden Sie unter G1GC und JIT Compile. -in-time-compiler /))

Wenn Sie sich jedoch nur die Startzeit ansehen, können Sie feststellen, dass es 100 Millisekunden bis einige Sekunden dauert, bis alle für die Anwendung verwendeten Threads abgeschlossen sind. Diese Funktion selbst ist ein Overhead, der für Anwendungen, die auf EC2 mit dem alten sogenannten Krasaba-Modell ausgeführt werden, fast ignoriert werden kann, für serverlose Anwendungen, die auf FaaS wie Lambda ausgeführt werden, jedoch niemals ignoriert werden kann.

** TypeScript basiert auf NodeJS und ist im Grunde ein einzelner Thread **. Asynchron wird von Jobwarteschlangen, Ereignisschleifen usw. verwaltet, nicht von separaten Threads oder Prozessen.

Daher erfordern die meisten Bibliotheken und Frameworks beim Start keine Thread-Erweiterung und erfordern wenig Overhead, um die Laufzeit zu starten.

** Riesiges Paketarchiv **

In Serverless ist die Paketarchivierung des Quellcodes grundsätzlich ** klein **.

Beim Start lädt der Lambda-Container die ** Quelle aus dem S3-Bucket für AWS-verwalteten Quellcode herunter und stellt sie im Container bereit. ** ** **

Die Downloadzeit von S3 ist normalerweise sehr kurz, aber wenn es um 100 MB oder 200 MB geht, kann sie nicht ignoriert werden.

NodeJS-Pakete sind grundsätzlich kleiner als Java.

Um ehrlich zu sein, habe ich nicht studiert und weiß nicht warum, aber ich denke, die folgenden Gründe können zusammenhängen. (Wenn Sie das wissen, lassen Sie es mich bitte in den Kommentaren wissen)

  • Viele Java-Frameworks und -Bibliotheken sind umfassend und bringen Abhängigkeiten mit sich, die für die Funktionen, die Sie ursprünglich verwenden möchten, nicht erforderlich sind. JavaScript verfügt jedoch über viele zweckspezifische Bibliotheken, und es ist möglich, die Abhängigkeiten auf das erforderliche Minimum zu reduzieren. Es gibt viele. Mit JavaScript (NodeJS) können Sie mehrere Module in eine Datei schreiben. Die Wartung ist einfach. Der wichtige Punkt für die Wartbarkeit in Java ist jedoch, dass die Quelle aufgrund der Dateidivision und der Paketverwaltung tendenziell wächst.

Eigentlich konnte ich beim Schreiben in Java Pakete mit maximal ** 200 MB ** erstellen, aber nach dem Wechsel zu NodeJS sind es nur ca. 35 MB **.

Dieses riesige Paketarchiv ist größtenteils auf unsere Versuche zurückzuführen, alten Code, der im Frühjahr geschrieben wurde, wiederzuverwenden. Tatsächlich erfordert jedoch selbst optimierter Code ohne diese unerwünschten Frameworks unbedingt 50 MB. Es ist geworden.

Nutzen Sie das JavaScript-Wissen und das Ökosystem

Da wir auch Webentwickler sind, schreiben wir im Grunde auch das Frontend. Daher hatte ich einige Kenntnisse in JavaScript und NodeJS.

Von der Blütezeit von jQuery bis zur Entwicklung moderner Frameworks wie React / Vue habe ich einige sprachliche Funktionen unterdrückt und werde bis zu einem gewissen Grad verstehen, wie man Code schreibt.

** TypeScript ist eine JavaScript-Erweiterungssprache, die eventuell in JavaScript transpiliert wird. ** ** **

Viele Grammatiken und Redewendungen werden von JavaScript geerbt, sodass wir den Service in kürzerer Zeit entwickeln können.

Darüber hinaus bieten ** die meisten großen NodeJS-Bibliotheken die für TypeScript erforderlichen Typdefinitionen **, sodass es eine große Freude war, die Vorteile des NodeJS-Ökosystems zu nutzen.

Sehr einfach zu implementierender Funktionstyp

Wenn wir über aktuelle technologische Trends sprechen, können wir nicht ohne den Aufstieg von Funktionstypen sprechen. Funktionale Implementierungen tragen naturgemäß wesentlich dazu bei, stabilen, einfachen, testbaren Code mit geringem Risiko zu schreiben.

Insbesondere im Fall von AWS Lambda ist die funktionale Implementierung, die den Status und die Nebenwirkungen isoliert, sehr kompatibel und einfach zu warten, da Code erforderlich ist, der den Status immer externalisiert.

Erstens hat JavaScript, wie John Resig, der Schöpfer von jQuery, in Das Geheimnis von JavaScript Ninja sagte, in erster Linie Unterstützung für funktionale Programmierung. Funktionen sind erstklassige Objekte in JavaScript, und jQuery wird tatsächlich mit der Erwartung erstellt, dass es als Funktionstyp geschrieben wird.

Andererseits kann der Versuch, Funktionscode in einer dynamisch typisierten Sprache zu schreiben, manchmal sehr ärgerlich sein. Beispielsweise ist die Anzahl der Funktionen, die nur durch primitive Typen ausgedrückt werden können, sehr begrenzt, und es ist normalerweise ziemlich gefährlich, Object als Rückgabewert oder Argument zu verwenden.

Mit TypeScript können Sie jedoch Typen für Argumente und Rückgabewerte angeben.

Darüber hinaus erweitern die folgenden TypeScript-Funktionen den Ausdrucksbereich für die von uns geschriebenen Funktionen und helfen uns, sichereren und einfacheren Code zu schreiben.

  • ** Typ: Häufig verwendete Typen können je nach Kontext eingegeben werden. (* String * und * UserId *, * Promise * und * Response * usw.) **
  • ** Schnittstelle / Klasse: Argumente und Rückgabewerte, die durch Object dargestellt werden, können durch einen Typ dargestellt werden, der dem Kontext entspricht. ** ** **
  • ** Enum: Ich muss nicht darüber reden **
  • ** Readonly: Sie können Ihren eigenen Typ unveränderlich machen **
  • ** Generika: Größeres Spektrum an Darstellungen für Funktionsschnittstellen **

TypeScript hat viele andere Funktionen, die sehr nützlich sind, wenn Sie versuchen, funktional zu schreiben, aber ich werde sie hier nicht alle auflisten. (Die meisten von ihnen sind von JavaScript abgeleitet)

Ich möchte irgendwo in der Zukunft einen Artikel über Funktionstypen und TypeScript schreiben.

Sie können die in Java erlernte Best Practice wiederverwenden

Wenn Sie die TypeScript-Grammatik lernen, werden Sie erstaunt sein, wie ** Sie etwas schreiben können, das Java oder Scala sehr ähnlich ist **.

Erstens haben wir während der Entwicklung für einen bestimmten Zeitraum in Java einige gute Code-Praktiken in Java gesammelt. Das gesammelte Know-how, wie das Entwerfen von Klassen und Schnittstellen, das effiziente Verwenden von Enum und das Schreiben von Stream-APIs zur Verbesserung der Wartbarkeit, konnte nicht weggeworfen werden.

Zusätzlich zu Schnittstellen und Klassen unterstützt TypeScript Zugriffsmodifikatoren und Readonly (endgültige Eigenschaften in Java), sodass wir das in Java gepflegte Know-how einführen konnten.

Dies beinhaltet ** objektorientierte Best Practices und Entwurfsmuster **. (Funktionsorientiert und objektorientiert sind nicht bilateral, daher denke ich, dass es in Ordnung ist, sie gleichzeitig in einem Projekt zu verwenden. Persönlich.)

Wenn wir Python oder Ruby verwenden würden, das eine leicht einzigartige Grammatik hat, hätten wir wahrscheinlich viel Zeit damit verbracht, zu entscheiden, wie die Praktiken zum Schreiben von Code höherer Qualität auf diese Sprache angewendet werden sollen. .. (Es macht Spaß, ich weiß, nur Zeit ...)

Natürlich habe ich nicht das gesamte Design und die Logik kopiert und eingefügt, sondern den größten Teil des Codes neu geschrieben. Ich denke jedoch, dass das Umschreiben in angemessener kurzer Zeit mit angemessener Qualität abgeschlossen wurde, obwohl der ungefähre Teil mit Kratzern umgeschrieben wurde.

Fazit

Wir müssen TypeScript noch auf einem Niveau lernen, das als Anfänger bezeichnet werden kann, aber wir genießen die Vorteile bereits mit aller Kraft.

Wenn ich jetzt gefragt werde, frage ich mich, ob Golang gut ist, Micronaut und GraalVM vielleicht interessant sind oder ob es andere Optionen gibt, aber ich bin im Moment sehr zufrieden mit TypeScript und es ist das Beste. Ich glaube, das ist eine der Optionen.

Natürlich ist die Verarbeitung langsam, aber Stapelverarbeitung, Parallelverarbeitung, verteilte Verarbeitung, Workflow-Design, API-Gateway-Timeout-Behandlung, Datenkonsistenz, Server usw. Ich bin auf viele Probleme gestoßen, die durch Les und TypeScript verursacht wurden.

Aber es hat viel Spaß gemacht, als Geek daran zu arbeiten, und einiges davon ist bereits die beste Vorgehensweise, oder? Ich habe auch einige Methoden gefunden. (Ich möchte dies später in einem Artikel schreiben.)

Wenn Sie gerade in Java an Serverless arbeiten und einen Serverless Shit, Tight oder nur einen normalen Server wollen, sollten Sie auf jeden Fall auch TypeScript ausprobieren. Ich hoffe, dass es produktiver wird, als ich es mir vorgestellt habe.

Vielen Dank für Ihre lange Beziehung. Wenn Sie Kommentare oder Korrekturen haben, zögern Sie bitte nicht, uns zu kontaktieren.

Recommended Posts