Alexey Naidenov. ITooLabs. Entwicklungsfall für die Telefonplattform Go (Golang). Teil 1

Alexey Naidenov, CEO ITooLabs, spricht über die Entwicklung einer Telekommunikationsplattform für Telekommunikationsbetreiber in der Programmiersprache Go (Golang). Alexey teilt auch seine Erfahrungen mit der Bereitstellung und dem Betrieb der Plattform bei einem der größten asiatischen Telekommunikationsbetreiber, der die Plattform zur Bereitstellung von Voicemail- (VoiceMail) und virtuellen PBX-Diensten (Cloud PBX) nutzte.

Alexey Naidenov. ITooLabs. Entwicklungsfall für die Telefonplattform Go (Golang). Teil 1

Alexey Naydenov (im Folgenden: AN): - Hallo alle! Mein Name ist Alexey Naidenov. Ich bin der Direktor von ITooLabs. Zunächst möchte ich beantworten, was ich hier mache und wie ich hierher gekommen bin.

Schaut man sich den Bitrix24-Marktplatz (Bereich „Telefonie“) an, dann sind es 14 Anwendungen und 36 davon (40 %):

Alexey Naidenov. ITooLabs. Entwicklungsfall für die Telefonplattform Go (Golang). Teil 1

Genauer gesagt sind das unsere Partnerbetreiber, aber dahinter steckt unsere Plattform (Platform as a Service) – was wir ihnen für einen kleinen Cent verkaufen. Eigentlich würde ich gerne über die Entwicklung dieser Plattform sprechen und wie wir zu Go gekommen sind.

Die Zahlen für unsere Plattform lauten jetzt:

Alexey Naidenov. ITooLabs. Entwicklungsfall für die Telefonplattform Go (Golang). Teil 1

44 Partnerbetreiber, darunter MegaFon. Im Allgemeinen lieben wir es, Abenteuer zu erleben, und wir haben hier in Russland Zugriff auf 100 Millionen Abonnenten von 44 Betreibern. Wenn also jemand eine Geschäftsidee hat, freuen wir uns immer über ein offenes Ohr.

  • 5000 Anwenderunternehmen.
  • Insgesamt 20 Abonnenten. Es ist alles B000B – wir arbeiten nur mit Unternehmen zusammen.
  • Tagsüber 300 Anrufe pro Minute.
  • 100 Millionen Gesprächsminuten im letzten Jahr (wir haben gefeiert). Dies gilt ohne Berücksichtigung der internen Verhandlungen, die auf unserer Plattform stattfinden.

Wie hat es angefangen?

Wie fangen die richtigen Jungs an, ihre eigene Plattform zu entwickeln? Es sollte auch berücksichtigt werden, dass wir eine Geschichte der Entwicklung von „Hardcore-Unternehmen“ hatten, und das sogar zum genauesten Zeitpunkt des Jahres für ein Unternehmen! Es war diese glückliche Zeit, als man zum Kunden kam und sagte: „Wir brauchen noch ein paar Server.“ Und der Kunde: „Ja, keine Frage! Wir haben eine Zehn im Regal.

Also haben wir Oracle, Java, WebSphere, Db2 und all das gemacht. Deshalb haben wir natürlich die besten Anbieterlösungen genommen, sie integriert und versucht, damit durchzustarten. Sie spielten alleine. Es wäre so ein internes Startup.

Alles begann im Jahr 2009. Seit 2006 sind wir auf die eine oder andere Weise eng in Betreiberentscheidungen eingebunden. Wir haben mehrere benutzerdefinierte virtuelle PBX-Anlagen erstellt (wie die, die wir jetzt bestellt haben): Wir haben nachgesehen, entschieden, dass sie gut ist, und beschlossen, ein internes Startup zu gründen.

Alexey Naidenov. ITooLabs. Entwicklungsfall für die Telefonplattform Go (Golang). Teil 1

Nehmen Sie VMWare. Da wir alleine unterwegs waren, mussten wir den coolen Anbieter Storage sofort verlassen. Wir wissen alles darüber: Versprechen sollten durch 3 geteilt und die Kosten mit 10 multipliziert werden. Deshalb haben wir DirDB erstellt und so weiter.

Dann begann es zu wachsen. Hinzu kam der Abrechnungsservice, da die Plattform damit nicht mehr zurechtkam. Dann wechselte der Abrechnungsserver von MySQL zu Mongo. Als Ergebnis haben wir eine funktionierende Lösung erhalten, die alle dort eingehenden Anrufe verarbeitet:

Alexey Naidenov. ITooLabs. Entwicklungsfall für die Telefonplattform Go (Golang). Teil 1

Aber irgendwo drinnen dreht sich das gleiche Herstellerprodukt – das wichtigste, nukleare Produkt, das wir einst genommen haben. Ungefähr Ende 2011 wurde uns klar, dass der größte Engpass für uns natürlich dieses spezielle Produkt sein wird – wir werden darauf stoßen. Wir sahen eine Wand vor uns, gegen die wir im vollen Galopp rannten, während Kunden liefen, kamen hinzu.
Dementsprechend mussten wir etwas tun. Natürlich haben wir viel über verschiedene Produkte recherchiert – sowohl Open-Source-Produkte als auch Anbieterprodukte. Darauf möchte ich jetzt nicht näher eingehen – das ist nicht der Punkt. Der allerletzte Ausweg, über den wir nachgedacht haben, war die Entwicklung einer eigenen Plattform.

Letztendlich sind wir zu dieser Option gekommen. Warum? Denn alle Anbieter- und Open-Source-Produkte wurden vor 10 Jahren entwickelt, um Probleme zu lösen. Nun, wenn ein 10-Jähriger und noch mehr! Die Wahl liegt für uns auf der Hand: Entweder wir verabschieden uns von unserer großartigen Idee eines idealen Service (für Partner, Betreiber und uns selbst), oder wir machen etwas Eigenes.

Wir haben beschlossen, etwas anderes zu machen!

Plattformanforderungen

Wenn man etwas über längere Zeit macht (das Produkt eines anderen ausnutzt), dann formiert sich langsam der Gedanke in deinem Kopf: Wie würde ich es selbst machen? Da wir alle Programmierer im Unternehmen sind (mit Ausnahme der Verkäufer gibt es keine Nicht-Programmierer), sind unsere Anforderungen schon seit langem formuliert und sie waren klar:

  1. Hohe Entwicklungsgeschwindigkeit. Das Produkt des Anbieters, das uns gequält hat, gefiel uns überhaupt nicht, weil alles lange und langsam geklappt hat. Wir wollten schnell – wir hatten viele Ideen! Wir haben immer noch viele Ideen, aber die Liste der Ideen war so groß, dass es schien, als wären es noch zehn Jahre. Jetzt nur noch für ein Jahr.
  2. Maximale Ausnutzung von Mehrkerneisen. Das war auch für uns wichtig, denn wir sahen, dass es immer mehr Kerne geben würde.
  3. Hohe Zuverlässigkeit. Der, den wir auch geweint haben.
  4. Hohe Fehlertoleranz.
  5. Wir wollten am Ende einen täglichen Release-Prozess haben. Dazu brauchten wir eine Sprachauswahl.

Alexey Naidenov. ITooLabs. Entwicklungsfall für die Telefonplattform Go (Golang). Teil 1

Dementsprechend erwachsen aus den Anforderungen an das Produkt, die wir für uns selbst dargestellt haben, die Anforderungen an die Sprache in klar logischer Weise.

  1. Wenn wir Unterstützung für Multi-Core-Systeme wollen, dann brauchen wir Unterstützung für die parallele Ausführung.
  2. Wenn wir Entwicklungsgeschwindigkeit brauchen, brauchen wir eine Sprache, die eine wettbewerbsfähige Entwicklung und wettbewerbsfähige Programmierung unterstützt. Falls jemand den Unterschied noch nicht bemerkt hat, dann ist es ganz einfach:
    • Bei der parallelen Programmierung geht es darum, wie zwei verschiedene Threads auf unterschiedlichen Kernen laufen.
    • Bei der gleichzeitigen Ausführung, genauer gesagt bei der Parallelitätsunterstützung, geht es darum, wie die Sprache (oder die Laufzeit, was auch immer) dabei hilft, die gesamte Komplexität zu verbergen, die mit der parallelen Ausführung einhergeht.
  3. Hohe Stabilität. Offensichtlich brauchten wir einen Cluster, und dieser war besser als das, was wir für das Produkt des Anbieters hatten.

Alexey Naidenov. ITooLabs. Entwicklungsfall für die Telefonplattform Go (Golang). Teil 1

Wenn Sie sich erinnern, hatten wir nicht wirklich viele Optionen. Erstens, Erlang – wir lieben es und wissen es, es war mein persönlicher Favorit. Zweitens ist Java nicht einmal Java, sondern speziell Scala. Drittens die Sprache, die wir damals überhaupt nicht kannten – Go. Es war damals gerade erst erschienen, genauer gesagt, es existierte bereits seit etwa zwei Jahren, war aber noch nicht veröffentlicht worden.

Go! besiegt

Geschichte von Go

Wir haben darauf eine Plattform gebaut. Ich werde versuchen zu erklären, warum.

Eine kurze Geschichte von Go. Begonnen im Jahr 2007, eröffnet im Jahr 2009, wurde die erste Version im Jahr 2012 veröffentlicht (das heißt, wir haben bereits vor der ersten Veröffentlichung mit der Arbeit begonnen). Der Initiator war Google, das, wie ich vermute, Java ersetzen wollte.

Die Autoren sind sehr berühmt:

  • Ken Thomson, der hinter Unix stand, UTF-8 erfand, arbeitete am Plan 9-System;
  • Rob Pike, der UTF-8 mit Ken entworfen hat, arbeitete auch an Plan 9, Inferno, Limbo bei Bell Labs;
  • Robert Gizmer, den wir kennen und lieben, weil er den Java HotSpot Compiler erfunden und am Generator in V8 (Googles Javascript-Interpreter) gearbeitet hat;
  • Und über 700 Mitwirkende, darunter einige unserer Patches.

Alexey Naidenov. ITooLabs. Entwicklungsfall für die Telefonplattform Go (Golang). Teil 1

Gehen Sie auf einen Blick

Wir sehen, dass die Sprache mehr oder weniger einfach und verständlich ist. Wir haben offensichtliche Typen: In einigen Fällen müssen sie deklariert werden, in anderen nicht (was bedeutet, dass die Typen trotzdem abgeleitet werden).

Alexey Naidenov. ITooLabs. Entwicklungsfall für die Telefonplattform Go (Golang). Teil 1

Man erkennt, dass es in Mode ist, Strukturen zu beschreiben. Es ist ersichtlich, dass wir das Konzept eines Zeigers haben (wo sich das Sternchen befindet). Es ist ersichtlich, dass es eine spezielle Unterstützung für die Deklaration der Initialisierung von Arrays und assoziativen Arrays gibt.

Grob verständlich – man kann leben. Ich versuche Hallo Welt zu schreiben:

Alexey Naidenov. ITooLabs. Entwicklungsfall für die Telefonplattform Go (Golang). Teil 1

Was sehen wir? Dies ist eine C-ähnliche Syntax, das Semikolon ist optional. Es kann ein Trennzeichen für zwei Zeilen sein, aber nur, wenn es sich um zwei Konstrukte handelt, die genau auf derselben Zeile liegen.

Wir sehen, dass die Klammern in den Kontrollstrukturen (in der 14. Zeile) optional sind, geschweifte Klammern jedoch immer erforderlich sind. Wir sehen, dass die Eingabe statisch ist. Tim wird in den meisten Fällen angezeigt. Dieses Beispiel ist etwas komplizierter als das übliche Hello, World – nur um zu zeigen, dass es eine Bibliothek gibt.

Was finden wir sonst noch wichtig? Der Code ist in Paketen organisiert. Und um das Paket in Ihrem eigenen Code verwenden zu können, müssen Sie es mit der Import-Direktive importieren – das ist auch wichtig. Wir fangen an – es funktioniert. Großartig!

Versuchen wir etwas Komplizierteres: Hallo Welt, aber jetzt ist es ein http-Server. Was sehen wir hier interessant?

Alexey Naidenov. ITooLabs. Entwicklungsfall für die Telefonplattform Go (Golang). Teil 1

Erstens fungiert die Funktion als Parameter. Das bedeutet, dass die Funktion, die wir haben, ein „Bürger erster Klasse“ ist und man damit viele interessante Dinge in einem funktionalen Stil machen kann. Als nächstes sehen wir das Unerwartete: Die Importanweisung verweist direkt auf das GitHub-Repository. Genau, so ist es – und im Übrigen sollte es auch so gemacht werden.

In Go ist die universelle Kennung eines Pakets die URL seines Repositorys. Es gibt ein spezielles Goget-Dienstprogramm, das sich um alle Abhängigkeiten kümmert, sie herunterlädt, installiert, kompiliert und bei Bedarf für die Verwendung vorbereitet. Gleichzeitig kennt sich Goget mit HTML-Meta aus. Dementsprechend können Sie ein http-Verzeichnis führen, das Links zu Ihrem spezifischen Repository enthält (wie wir es beispielsweise tun).

Was sehen wir sonst noch? Http und Json in der regulären Bibliothek. Es gibt natürlich Selbstbeobachtung – Reflexion, die bei der Codierung von /json verwendet werden sollte, weil wir sie einfach durch ein beliebiges Objekt ersetzen.

Wir führen es aus und sehen, dass wir 20 Zeilen nützlichen Codes haben, der kompiliert, ausgeführt wird und die aktuelle durchschnittliche Auslastung der Maschine (auf der Maschine, auf der er läuft) angibt.
Was ist von dem, was wir hier sofort erkennen können, noch wichtig? Es wird in eine statische Binärdatei (buinary) kompiliert. Diese Binärdatei hat überhaupt keine Abhängigkeiten, keine Bibliotheken! Es kann auf jedes System kopiert, sofort ausgeführt werden und funktioniert.

Bewegen Sie sich auf.

Go: Methoden und Schnittstellen

Go hat Methoden. Sie können eine Methode für jeden benutzerdefinierten Typ deklarieren. Darüber hinaus handelt es sich nicht unbedingt um eine Struktur, sondern möglicherweise um einen Alias. Sie können einen Alias ​​für N32 deklarieren und Methoden schreiben, damit es etwas Nützliches tut.

Und hier geraten wir zum ersten Mal in eine Benommenheit ... Es stellt sich heraus, dass es in Go keine Klassen als solche gibt. Diejenigen, die Go kennen, sagen vielleicht, dass es Typinklusion gibt, aber das ist etwas völlig anderes. Je früher der Entwickler aufhört, es als Vererbung zu betrachten, desto besser. In Go gibt es keine Klassen und auch keine Vererbung.

Frage! Was hat uns die von Google geführte Autorengesellschaft gegeben, um die Komplexität der Welt abzubilden? Wir haben Schnittstellen geschenkt bekommen!

Alexey Naidenov. ITooLabs. Entwicklungsfall für die Telefonplattform Go (Golang). Teil 1

Eine Schnittstelle ist ein spezieller Typ, der das Schreiben einfacher Methoden und Methodensignaturen ermöglicht. Darüber hinaus entspricht jeder Typ, für den diese Methoden existieren (ausgeführt werden), dieser Schnittstelle. Das bedeutet, dass Sie einfach die entsprechende Funktion für einen Typ schreiben können, für einen anderen (der diesem Schnittstellentyp entspricht). Als nächstes deklarieren Sie eine Variable vom Typ dieser Schnittstelle und weisen ihr eines dieser Objekte zu.

Für Hardcore-Fans kann ich sagen, dass diese Variable tatsächlich zwei Zeiger enthält: einen auf Daten, den anderen auf eine spezielle Deskriptortabelle, die für diesen bestimmten Typ spezifisch ist, auf die Schnittstelle dieses Typs. Das heißt, der Compiler erstellt solche Deskriptortabellen zum Zeitpunkt der Verknüpfung.

Und es gibt natürlich Hinweise auf void in Go. Das Wort interface {} (mit zwei geschweiften Klammern) ist eine Variable, mit der man prinzipiell auf jedes beliebige Objekt zeigen kann.
Bisher ist alles in Ordnung, alles ist bekannt. Nichts Überraschendes.

Go: Goroutinen

Nun kommen wir zu dem, was uns interessiert: Leichtgewichtige Prozesse – Goroutinen (Goroutinen) in der Go-Terminologie.

Alexey Naidenov. ITooLabs. Entwicklungsfall für die Telefonplattform Go (Golang). Teil 1

  1. Erstens sind sie wirklich leicht (weniger als 2 KB).
  2. Zweitens sind die Kosten für die Erstellung einer solchen Goroutine vernachlässigbar: Sie können tausende davon pro Sekunde erstellen – es wird nichts passieren.
  3. Sie werden von einem eigenen Scheduler bedient, der einfach die Kontrolle von einer Goroutine auf eine andere überträgt.
  4. In diesem Fall wird die Kontrolle in folgenden Fällen übertragen:
    • wenn eine Go-Anweisung angetroffen wird (wenn die Goroutine die nächste Goroutine startet);
    • wenn ein blockierender Input/Out-Aufruf aktiviert ist;
    • wenn die Speicherbereinigung ausgelöst wird;
    • wenn eine Operation mit Kanälen gestartet wird.

Das heißt, wenn ein Go-Programm auf einem Computer ausgeführt wird, erkennt es die Anzahl der Kerne im System und startet so viele Threads wie nötig (wie viele Kerne sich im System befinden oder wie viele Sie ihm zugewiesen haben). Dementsprechend führt der Scheduler diese einfachen Ausführungsthreads auf allen Betriebssystemthreads in jedem Kern aus.

Es ist zu beachten, dass dies die effizienteste Art ist, Eisen zu verwerten. Zusätzlich zu dem, was wir gezeigt haben, machen wir noch viel mehr. Wir stellen beispielsweise DPI-Systeme her, die die Bereitstellung von 40 Gigabit in einer Einheit ermöglichen (abhängig davon, was in diesen Leitungen passiert).

Dort haben wir bereits vor Go genau das gleiche Schema aus genau diesem Grund verwendet: Da es Ihnen ermöglicht, die Lokalität des Prozessor-Cache zu speichern, wird die Anzahl der Betriebssystem-Kontextwechsel erheblich reduziert (was auch sehr lange dauert). Ich wiederhole: Dies ist die effektivste Art, Eisen zu verwerten.

Dieses einfache 21-Zeilen-Beispiel ist ein Beispiel, das einfach einen Echo-Server ausführt. Beachten Sie gleichzeitig, dass die Serve-Funktion äußerst einfach und linear ist. Es gibt keine Rückrufe, kein Grund zum Nachdenken... Sie lesen und schreiben einfach!

Gleichzeitig sollte es beim Lesen und Schreiben eigentlich blockieren – diese Goroutine wird einfach in die Warteschlange gestellt und vom Scheduler übernommen, wenn die Ausführung wieder möglich wird. Das heißt, dieser einfache Code kann als Echoserver für so viele Verbindungen fungieren, wie das Betriebssystem auf diesem Computer zulässt.

Demnächst geht es weiter...

Einige Anzeigen 🙂

Vielen Dank, dass Sie bei uns geblieben sind. Gefallen Ihnen unsere Artikel? Möchten Sie weitere interessante Inhalte sehen? Unterstützen Sie uns, indem Sie eine Bestellung aufgeben oder an Freunde weiterempfehlen. Cloud-VPS für Entwickler ab 4.99 $, ein einzigartiges Analogon von Einstiegsservern, das von uns für Sie erfunden wurde: Die ganze Wahrheit über VPS (KVM) E5-2697 v3 (6 Kerne) 10 GB DDR4 480 GB SSD 1 Gbit/s ab 19 $ oder wie teilt man sich einen Server? (verfügbar mit RAID1 und RAID10, bis zu 24 Kerne und bis zu 40 GB DDR4).

Dell R730xd 2-mal günstiger im Equinix Tier IV-Rechenzentrum in Amsterdam? Nur hier 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6 GHz 14C 64 GB DDR4 4 x 960 GB SSD 1 Gbit/s 100 TV ab 199 $ in den Niederlanden! Dell R420 – 2x E5-2430 2.2 GHz 6C 128 GB DDR3 2 x 960 GB SSD 1 Gbit/s 100 TB – ab 99 $! Lesen über Wie baut man ein Infrastrukturunternehmen auf? Klasse mit dem Einsatz von Dell R730xd E5-2650 v4 Servern im Wert von 9000 Euro für einen Cent?

Source: habr.com

Kommentar hinzufügen