Alexey Naidenov. ITooLabs. Ontwikkelingscase op Go (Golang) telefoonplatform. Deel 1

Alexey Naidenov, CEO ITooLabs, vertelt over de ontwikkeling van een telecommunicatieplatform voor telecomoperators in de programmeertaal Go (Golang). Alexey deelt ook zijn ervaring met het implementeren en bedienen van het platform bij een van de grootste Aziatische telecomoperators, die het platform gebruikte om voicemail (VoiceMail) en Virtual PBX (Cloud PBX)-diensten aan te bieden.

Alexey Naidenov. ITooLabs. Ontwikkelingscase op Go (Golang) telefoonplatform. Deel 1

Alexey Naydenov (hierna - AN): - Dag Allemaal! Mijn naam is Alexey Naidenov. Ik ben de directeur van ITooLabs. Allereerst wil ik graag beantwoorden wat ik hier doe en hoe ik hier terecht ben gekomen.

Als je kijkt naar de Bitrix24 Marketplace (sectie "Telefonie"), dan zijn 14 applicaties en 36 die er zijn (40%) van ons:

Alexey Naidenov. ITooLabs. Ontwikkelingscase op Go (Golang) telefoonplatform. Deel 1

Om precies te zijn, dit zijn onze partneroperators, maar achter dit alles staat ons platform (Platform as a Service) - wat we hen voor een kleine cent verkopen. Eigenlijk wil ik het hebben over de ontwikkeling van dit platform en hoe we tot Go zijn gekomen.

De cijfers voor ons platform zijn nu:

Alexey Naidenov. ITooLabs. Ontwikkelingscase op Go (Golang) telefoonplatform. Deel 1

44 partneroperators, waaronder MegaFon. Over het algemeen houden we ervan om op avontuur te gaan, en we hebben zelfs toegang tot 100 miljoen abonnees van 44 operators hier in Rusland. Daarom, als iemand zakelijke ideeën heeft, luisteren we daar graag naar.

  • 5000 gebruikersbedrijven.
  • In totaal 20 abonnees. Het is allemaal b000b - we werken alleen met bedrijven.
  • 300 oproepen per minuut gedurende de dag.
  • Vorig jaar 100 miljoen belminuten (dat hebben we gevierd). Dit is zonder rekening te houden met de interne onderhandelingen die op ons platform plaatsvinden.

Hoe begon het?

Hoe beginnen de juiste kerels hun eigen platform te maken? We moeten er ook rekening mee houden dat we een geschiedenis hadden van "hardcore enterprise"-ontwikkeling, en zelfs op de meest nauwkeurige tijd van het jaar voor een onderneming! Het was die gelukkige tijd dat je naar de klant komt en zegt: "We hebben nog een paar servers nodig." En de klant: “Ja, geen twijfel mogelijk! We hebben een tien in het rek.

Dus we deden Oracle, Java, WebSphere, Db2 en zo. Daarom hebben we natuurlijk de beste leveranciersoplossingen genomen, deze geïntegreerd en geprobeerd ermee van start te gaan. Ze speelden op zichzelf. Het zou zo'n interne startup zijn.

Het begon allemaal in 2009. Sinds 2006 zijn we op de een of andere manier nauw betrokken bij beslissingen van operators. We hebben verschillende virtuele PBX'en op maat gemaakt (zoals wat we nu in bestelling hebben): we keken, besloten dat het goed was en besloten een interne startup op gang te brengen.

Alexey Naidenov. ITooLabs. Ontwikkelingscase op Go (Golang) telefoonplatform. Deel 1

Neem VMWare. Omdat we alleen liepen, moesten we de coole verkoper Storage onmiddellijk verlaten. We weten er alles van: dat beloften moeten worden gedeeld door 3 en de kosten moeten worden vermenigvuldigd met 10. Daarom hebben we DirDB gedaan, enzovoort.

Toen begon het te groeien. Daar kwam de facturatieservice bij, omdat het platform het niet meer aankon. Vervolgens verhuisde de factureringsserver van MySQL naar Mongo. Als resultaat kregen we een werkende oplossing die alle oproepen verwerkt die daar naartoe gaan:

Alexey Naidenov. ITooLabs. Ontwikkelingscase op Go (Golang) telefoonplatform. Deel 1

Maar ergens binnenin draait hetzelfde product van de leverancier - het belangrijkste, nucleaire, dat we ooit hebben genomen. Ongeveer eind 2011 realiseerden we ons dat het belangrijkste knelpunt voor ons natuurlijk dit specifieke product zal zijn - we zullen het tegenkomen. We zagen een muur voor ons, waar we in volle galop tegenaan renden, terwijl klanten liepen, werden toegevoegd.
Daarom moesten we iets doen. Natuurlijk hebben we behoorlijk wat onderzoek gedaan naar verschillende producten - zowel open source als leveranciersproducten. Ik zal hier nu niet bij stilstaan ​​- daar gaat het niet om. De allerlaatste fallback waar we aan dachten, was het maken van ons eigen platform.

Uiteindelijk zijn we tot deze optie gekomen. Waarom? Omdat alle vendor- en open source-producten 10 jaar geleden zijn gemaakt om problemen op te lossen. Nou ja, als een 10-jarige, en nog wat meer! De keuze is voor ons duidelijk geworden: ofwel nemen we afscheid van ons mooie idee van een ideale service (voor partners, operators en onszelf), ofwel gaan we zelf iets doen.

We besloten iets anders te doen!

Platformvereisten

Als je iets lang doet (je buit andermans product uit), dan vormt zich langzaam de gedachte in je hoofd: hoe zou ik het zelf doen? Aangezien we allemaal programmeurs in het bedrijf zijn (behalve verkopers, er zijn geen niet-programmeurs), zijn onze vereisten al lang gevormd en ze waren duidelijk:

  1. Hoge ontwikkelingssnelheid. Het product van de verkoper, dat ons kwelde, paste in de eerste plaats niet bij ons omdat alles lang en langzaam werkte. We wilden snel – we hadden veel ideeën! We hebben nog steeds veel ideeën, maar toen was de lijst met ideeën zo dat het wel tien jaar vooruit leek. Nu nog maar voor een jaar.
  2. Maximaal gebruik van meeraderig ijzer. Dit was voor ons ook belangrijk, want we zagen dat er alleen maar meer en meer kernen zouden komen.
  3. Hoge betrouwbaarheid. Degene die we ook huilden.
  4. Hoge fouttolerantie.
  5. We wilden eindigen met een dagelijks releaseproces. Hiervoor hadden we een taalkeuze nodig.

Alexey Naidenov. ITooLabs. Ontwikkelingscase op Go (Golang) telefoonplatform. Deel 1

Dienovereenkomstig groeien uit de vereisten voor het product die we voor onszelf hebben gepresenteerd, de vereisten voor de taal op een duidelijk logische manier.

  1. Als we ondersteuning willen voor multi-core systemen, dan hebben we ondersteuning nodig voor parallelle uitvoering.
  2. Als we ontwikkelingssnelheid nodig hebben, hebben we een taal nodig die competitieve ontwikkeling ondersteunt, competitieve programmering. Als iemand het verschil niet is tegengekomen, dan is het heel simpel:
    • parallel programmeren gaat over hoe twee verschillende threads op verschillende cores draaien;
    • gelijktijdige uitvoering, meer specifiek gelijktijdige ondersteuning, gaat over hoe de taal (of runtime, wat dan ook) helpt om alle complexiteit te verbergen die voortkomt uit parallelle uitvoering.
  3. Hoge stabiliteit. Het was duidelijk dat we een cluster nodig hadden en dat was beter dan wat we hadden op het product van de leverancier.

Alexey Naidenov. ITooLabs. Ontwikkelingscase op Go (Golang) telefoonplatform. Deel 1

We hadden niet echt veel opties, als je je dat herinnert. Ten eerste, Erlang - we houden ervan en weten het, het was mijn persoonlijke, persoonlijke favoriet. Ten tweede is Java niet eens Java, maar specifiek Scala. Ten derde, de taal die we op dat moment helemaal niet kenden - Go. Het was toen net verschenen, om precies te zijn, het bestond al ongeveer twee jaar, maar was nog niet uitgebracht.

Verslagen Go!

Geschiedenis van Ga

We hebben er een platform op gemaakt. Ik zal proberen uit te leggen waarom.

Een korte geschiedenis van Go. Gestart in 2007, geopend in 2009, de eerste versie werd uitgebracht in 2012 (dat wil zeggen, we begonnen al te werken vóór de eerste release). De initiatiefnemer was Google, dat naar ik vermoed Java wilde vervangen.

De auteurs zijn erg beroemd:

  • Ken Thomson, die achter Unix zat, vond UTF-8 uit, werkte aan het Plan 9-systeem;
  • Rob Pike, die samen met Ken UTF-8 ontwierp, werkte ook aan Plan 9, Inferno, Limbo bij Bell Labs;
  • Robert Gizmer, die we kennen en waar we van houden voor het uitvinden van de Java HotSpot Compiler en voor het werken aan de generator in V8 (Google's Javascript-interpreter);
  • En meer dan 700 bijdragers, waaronder enkele van onze patches.

Alexey Naidenov. ITooLabs. Ontwikkelingscase op Go (Golang) telefoonplatform. Deel 1

Ga in een oogopslag

We zien dat de taal min of meer eenvoudig en begrijpelijk is. We hebben voor de hand liggende typen: in sommige gevallen moeten ze worden gedeclareerd, in andere niet (wat betekent dat de typen toch worden afgeleid).

Alexey Naidenov. ITooLabs. Ontwikkelingscase op Go (Golang) telefoonplatform. Deel 1

Het is duidelijk dat het in de mode is om structuren te beschrijven. Het is te zien dat we het concept van een aanwijzer hebben (waar de asterisk is). Het is te zien dat er speciale ondersteuning is voor het declareren van initialisatie van arrays en associatieve arrays.

Grofweg begrijpelijk - je kunt leven. Ik probeer Hallo wereld te schrijven:

Alexey Naidenov. ITooLabs. Ontwikkelingscase op Go (Golang) telefoonplatform. Deel 1

Wat zien we? Dit is C-achtige syntaxis, de puntkomma is optioneel. Het kan een scheidingsteken zijn voor twee regels, maar alleen als dit twee constructies zijn die exact op dezelfde regel staan.

We zien dat de haakjes in de besturingsstructuren (op de 14e regel) optioneel zijn, maar gekrulde zijn altijd verplicht. We zien dat het typen statisch is. Tim wordt in de meeste gevallen weergegeven. Dit voorbeeld is iets gecompliceerder dan de gebruikelijke Hallo wereld - alleen om te laten zien dat er een bibliotheek is.

Wat vinden we nog meer belangrijk? De code is georganiseerd in pakketten. En om het pakket in uw eigen code te gebruiken, moet u het importeren met behulp van de importrichtlijn - dit is ook belangrijk. We beginnen - het werkt. Geweldig!

Laten we iets ingewikkelder proberen: Hallo, wereld, maar nu is het een http-server. Wat zien we hier interessant?

Alexey Naidenov. ITooLabs. Ontwikkelingscase op Go (Golang) telefoonplatform. Deel 1

Ten eerste fungeert de functie als een parameter. Dit betekent dat de functie die we hebben een "eersteklasburger" is en dat je er in een functionele stijl veel interessante dingen mee kunt doen. We zien het onverwachte volgende: de importrichtlijn verwijst rechtstreeks naar de GitHub-repository. Dat klopt, zo is het - bovendien, zo moet het.

In Go is de universele identificatie van een pakket de url van de repository. Er is een speciaal Goget-hulpprogramma dat voor alle afhankelijkheden geldt, ze downloadt, installeert, compileert en indien nodig voorbereidt voor gebruik. Tegelijkertijd weet Goget van html-meta. Dienovereenkomstig kunt u een http-directory bijhouden, die links naar uw specifieke repository zal bevatten (zoals wij bijvoorbeeld doen).

Wat zien we nog meer? Http en Json in de reguliere bibliotheek. Er is duidelijk introspectie - reflectie, die zou moeten worden gebruikt bij het coderen van / json, omdat we er gewoon een willekeurig object voor vervangen.

We voeren het uit en zien dat we 20 regels bruikbare code hebben die compileert, draait en de huidige gemiddelde belasting van de machine geeft (op de machine waarop deze draait).
Wat is er nog meer belangrijk aan wat we hier meteen kunnen zien? Het compileert in één statisch binair bestand (buinary). Dit binaire bestand heeft helemaal geen afhankelijkheden, geen bibliotheken! Het kan naar elk systeem worden gekopieerd, onmiddellijk worden uitgevoerd en het zal werken.

Bewegen op.

Go: methoden en interfaces

Go heeft methoden. U kunt een methode declareren voor elk aangepast type. Bovendien is dit niet noodzakelijkerwijs een structuur, maar kan het een of ander alias zijn. U kunt een alias voor N32 declareren en methoden schrijven om iets nuttigs te doen.

En hier vallen we voor het eerst in een roes ... Het blijkt dat Go als zodanig geen lessen heeft. Degenen die Go kennen, zeggen misschien dat er type-inclusie is, maar dit is totaal anders. Hoe eerder de ontwikkelaar het niet meer als erfenis beschouwt, hoe beter. Er zijn geen klassen in Go en er is ook geen overerving.

Vraag! Wat heeft het gezelschap van auteurs onder leiding van Google ons gegeven om de complexiteit van de wereld weer te geven? We hebben interfaces gekregen!

Alexey Naidenov. ITooLabs. Ontwikkelingscase op Go (Golang) telefoonplatform. Deel 1

Een interface is een speciaal type waarmee u eenvoudige methoden, methodehandtekeningen, kunt schrijven. Verder zal elk type waarvoor deze methoden bestaan ​​(worden uitgevoerd) overeenkomen met deze interface. Dit betekent dat u eenvoudig de corresponderende functie voor het ene type kunt schrijven, voor het andere (wat overeenkomt met dat interfacetype). Declareer vervolgens een variabele van het type van deze interface en wijs er een van deze objecten aan toe.

Voor hardcore fans kan ik zeggen dat deze variabele eigenlijk twee verwijzingen zal bevatten: een naar gegevens, de andere naar een speciale descriptortabel die specifiek is voor dit specifieke type, naar de interface van dit type. Dat wil zeggen, de compiler maakt dergelijke tabellen met descriptoren op het moment van koppelen.

En er zijn natuurlijk aanwijzingen om ongeldig te worden in Go. Het woord interface {} (met twee accolades) is een variabele waarmee je in principe naar elk willekeurig object kunt wijzen.
Tot nu toe is alles in orde, alles is bekend. Niets verrassends.

Ga naar: goroutines

Nu komen we bij waar we in geïnteresseerd zijn: lichtgewicht processen - goroutines (goroutines) in Go-terminologie.

Alexey Naidenov. ITooLabs. Ontwikkelingscase op Go (Golang) telefoonplatform. Deel 1

  1. Ten eerste zijn ze erg licht van gewicht (minder dan 2 Kb).
  2. Ten tweede zijn de kosten voor het maken van zo'n goroutine verwaarloosbaar: je kunt er duizend per seconde maken - er gebeurt niets.
  3. Ze worden bediend door hun eigen planner, die de controle eenvoudig van de ene goroutine naar de andere overdraagt.
  4. In dit geval wordt de zeggenschap overgedragen in de volgende gevallen:
    • als een go-instructie wordt aangetroffen (als de goroutine de volgende goroutine start);
    • als een blokkerende Input/Out-oproep is ingeschakeld;
    • als afvalinzameling wordt geactiveerd;
    • als een bewerking met kanalen wordt gestart.

Dat wil zeggen, wanneer een Go-programma op een computer wordt uitgevoerd, detecteert het het aantal kernen in het systeem, start het zoveel threads als nodig is (hoeveel kernen zijn er in het systeem, of hoeveel u het hebt opgedragen). Dienovereenkomstig zal de planner deze lichtgewicht uitvoeringsdraden uitvoeren op al deze besturingssysteemthreads in elke kern.

Opgemerkt moet worden dat dit de meest efficiënte manier is om ijzer te gebruiken. Naast wat we hebben laten zien, doen we nog veel meer. We maken bijvoorbeeld DPI-systemen die het mogelijk maken om 40 gigabit in één unit te bedienen (afhankelijk van wat er in deze lijnen gebeurt).

Daar, zelfs vóór Go, gebruikten we precies hetzelfde schema om deze reden: omdat je hiermee de locatie van de processorcache kunt opslaan, kun je het aantal OS-contextwisselingen aanzienlijk verminderen (wat ook erg lang duurt). Ik herhaal: dit is de meest effectieve manier om ijzer te gebruiken.

Dit eenvoudige voorbeeld van 21 regels is een voorbeeld dat gewoon echo-server doet. Merk tegelijkertijd op dat de serve-functie uiterst eenvoudig is, het is lineair. U hoeft niet teruggebeld te worden, u hoeft niet na te denken... U hoeft alleen maar te lezen en te schrijven!

Tegelijkertijd, als je leest en schrijft, zou het eigenlijk moeten blokkeren - deze goroutine wordt gewoon in de wachtrij geplaatst en door de planner gebruikt wanneer uitvoering weer mogelijk wordt. Dat wil zeggen, deze eenvoudige code kan fungeren als een echoserver voor zoveel verbindingen als het besturingssysteem op deze machine toestaat.

Wordt zeer binnenkort vervolgd...

Sommige advertenties 🙂

Bedankt dat je bij ons bent gebleven. Vind je onze artikelen leuk? Wil je meer interessante inhoud zien? Steun ons door een bestelling te plaatsen of door vrienden aan te bevelen, cloud VPS voor ontwikkelaars vanaf $ 4.99, een unieke analoog van servers op instapniveau, die door ons voor u is uitgevonden: De hele waarheid over VPS (KVM) E5-2697 v3 (6 kernen) 10 GB DDR4 480 GB SSD 1 Gbps vanaf $ 19 of hoe een server te delen? (beschikbaar met RAID1 en RAID10, tot 24 cores en tot 40GB DDR4).

Dell R730xd 2x goedkoper in Equinix Tier IV datacenter in Amsterdam? Alleen hier 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV vanaf $199 in Nederland! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - vanaf $99! Lees over Hoe infrastructuur corp te bouwen. klasse met het gebruik van Dell R730xd E5-2650 v4-servers ter waarde van 9000 euro voor een cent?

Bron: www.habr.com

Voeg een reactie