Alexey Naidenov. ITooLabs. Utvecklingsfall på Go (Golang) telefonplattform. Del 1

Alexey Naidenov, VD ITooLabs, berättar om utvecklingen av en telekommunikationsplattform för teleoperatörer i programmeringsspråket Go (Golang). Alexey delar också med sig av sin erfarenhet av att distribuera och driva plattformen i en av de största asiatiska telekomoperatörerna, som använde plattformen för att tillhandahålla tjänster för röstbrevlåda (VoiceMail) och Virtual PBX (Cloud PBX).

Alexey Naidenov. ITooLabs. Utvecklingsfall på Go (Golang) telefonplattform. Del 1

Alexey Naydenov (nedan - AN): - Hej alla! Jag heter Alexey Naidenov. Jag är chef för ITooLabs. Först och främst skulle jag vilja svara på vad jag gör här och hur jag hamnade här.

Om du tittar på Bitrix24 Marketplace (avsnittet "Telefoni"), så är 14 applikationer och 36 som finns där (40%) vi:

Alexey Naidenov. ITooLabs. Utvecklingsfall på Go (Golang) telefonplattform. Del 1

Mer exakt är det våra partneroperatörer, men bakom allt detta ligger vår plattform (Platform as a Service) – det vi säljer till dem för en liten slant. Egentligen skulle jag vilja prata om utvecklingen av den här plattformen och hur vi kom till Go.

Siffrorna för vår plattform är nu:

Alexey Naidenov. ITooLabs. Utvecklingsfall på Go (Golang) telefonplattform. Del 1

44 partneroperatörer, inklusive MegaFon. Generellt sett älskar vi att åka på äventyr, och vi har faktiskt tillgång till 100 miljoner abonnenter av 44 operatörer här i Ryssland. Därför, om någon har några affärsidéer, lyssnar vi alltid gärna på dem.

  • 5000 användarföretag.
  • 20 000 prenumeranter totalt. Allt är b2b – vi jobbar bara med företag.
  • 300 samtal per minut under dagen.
  • 100 miljoner samtalsminuter förra året (vi firade). Detta utan att ta hänsyn till de interna förhandlingar som finns på vår plattform.

Hur började det?

Hur börjar de rätta killarna göra sin egen plattform? Vi måste också ta hänsyn till att vi har haft en historia av "hardcore enterprise"-utveckling, och till och med vid den mest exakta tiden på året för ett företag! Det var den där glada tiden när du kommer till kunden och säger: "Vi behöver ett par servrar till." Och kunden: ”Ja, ingen fråga! Vi har en tia i hyllan.

Så vi gjorde Oracle, Java, WebSphere, Db2 och allt det där. Därför tog vi naturligtvis de bästa leverantörslösningarna, integrerade dem och försökte ta fart med det. De spelade på egen hand. Det skulle vara en sådan intern startup.

Allt började 2009. Sedan 2006 har vi varit nära involverade i operatörsbeslut, på ett eller annat sätt. Vi gjorde flera anpassade virtuella PBX:er (som vad vi nu har på beställning): vi tittade, bestämde oss för att det var bra och bestämde oss för att starta en intern start.

Alexey Naidenov. ITooLabs. Utvecklingsfall på Go (Golang) telefonplattform. Del 1

Ta VMWare. Eftersom vi gick på egen hand var vi tvungna att omedelbart överge den coola leverantören Storage. Vi vet allt om dem: att löften ska delas med 3, och kostnaden ska multipliceras med 10. Därför gjorde vi DirDB och så vidare.

Sedan började det växa. Faktureringstjänsten lades till detta, eftersom plattformen inte längre klarade av. Sedan flyttade faktureringsservern från MySQL till Mongo. Som ett resultat fick vi en fungerande lösning som behandlar alla samtal som går dit:

Alexey Naidenov. ITooLabs. Utvecklingsfall på Go (Golang) telefonplattform. Del 1

Men någonstans inuti snurrar samma leverantörsprodukt - den huvudsakliga kärnkraftsprodukten, som vi en gång tog. Ungefär i slutet av 2011 insåg vi själva att den största flaskhalsen för oss, naturligtvis, kommer att vara just den här produkten - vi kommer att stöta på den. Vi såg en vägg framför oss, som vi sprang i i full galopp, när kunderna gick, lades till.
Därför var vi tvungna att göra något. Naturligtvis gjorde vi ganska mycket research på olika produkter - både öppen källkod och leverantörs. Jag ska inte uppehålla mig vid detta nu - det är inte meningen. Den allra sista reserv som vi tänkte på var att skapa vår egen plattform.

Till slut kom vi fram till det här alternativet. Varför? Eftersom alla leverantörer och produkter med öppen källkod skapades för att lösa problem för 10 år sedan. Tja, om en 10-åring, och några till! Valet har blivit självklart för oss: antingen säger vi adjö till vår fantastiska idé om en idealisk tjänst (för partners, operatörer och oss själva), eller så gör vi något eget.

Vi bestämde oss för att göra något annorlunda!

Plattformskrav

Om du gör något under en längre tid (du utnyttjar någon annans produkt), så formas tanken långsamt i ditt huvud: hur skulle jag göra det själv? Eftersom vi alla är programmerare i företaget (förutom säljare, det finns inga icke-programmerare) har våra krav formats under lång tid, och de var tydliga:

  1. Hög utvecklingshastighet. Försäljarens produkt, som plågade oss, passade inte oss i första hand eftersom allt fungerade under lång tid och långsamt. Vi ville snabbt – vi hade många idéer! Vi har fortfarande många idéer, men då var idélistan sådan att det verkade vara tio år framåt. Nu bara i ett år.
  2. Maximalt utnyttjande av flerkärnigt järn. Detta var också viktigt för oss, eftersom vi såg att det bara skulle bli fler och fler kärnor.
  3. Hög tillförlitlighet. Den vi grät också.
  4. Hög feltolerans.
  5. Vi ville avsluta med en daglig releaseprocess. För att göra detta behövde vi ett språkval.

Alexey Naidenov. ITooLabs. Utvecklingsfall på Go (Golang) telefonplattform. Del 1

Följaktligen, från de krav på produkten som vi har presenterat för oss själva, växer kraven på språket på ett klart logiskt sätt.

  1. Om vi ​​vill ha stöd för flerkärniga system behöver vi stöd för parallellt exekvering.
  2. Om vi ​​behöver utvecklingshastighet behöver vi ett språk som stödjer konkurrenskraftig utveckling, konkurrenskraftig programmering. Om någon inte har stött på skillnaden är det väldigt enkelt:
    • parallell programmering handlar om hur två olika trådar löper på olika kärnor;
    • samtidig exekvering, närmare bestämt samtidighetsstöd, handlar om hur språket (eller körtiden, vad som helst) hjälper till att dölja all komplexitet som kommer från parallell exekvering.
  3. Hög stabilitet. Uppenbarligen behövde vi ett kluster, och det var bättre än vad vi hade på leverantörsprodukten.

Alexey Naidenov. ITooLabs. Utvecklingsfall på Go (Golang) telefonplattform. Del 1

Vi hade egentligen inte många alternativ, om du kommer ihåg. För det första, Erlang - vi älskar det och vet det, det var min personliga, personliga favorit. För det andra är Java inte ens Java, utan specifikt Scala. För det tredje språket som vi på den tiden inte kunde alls - Go. Den hade precis dykt upp då, närmare bestämt, den hade redan funnits i ungefär två år, men hade ännu inte släppts.

Besegrade Go!

Gos historia

Vi gjorde en plattform på den. Jag ska försöka förklara varför.

En kort historia om Go. Startade 2007, öppnade 2009, den första versionen släpptes 2012 (det vill säga vi började arbeta redan innan den första releasen). Initiativtagare var Google, som ville ersätta, som jag misstänker, Java.

Författarna är mycket kända:

  • Ken Thomson, som låg bakom Unix, uppfann UTF-8, arbetade på Plan 9-systemet;
  • Rob Pike, som designade UTF-8 med Ken, arbetade också på Plan 9, Inferno, Limbo på Bell Labs;
  • Robert Gizmer, som vi känner och älskar för att ha uppfunnit Java HotSpot-kompilatorn och för att ha arbetat med generatorn i V8 (Googles Javascript-tolkare);
  • Och över 700 bidragsgivare, inklusive några av våra patchar.

Alexey Naidenov. ITooLabs. Utvecklingsfall på Go (Golang) telefonplattform. Del 1

Gå med en blick

Vi ser att språket är mer eller mindre enkelt och begripligt. Vi har uppenbara typer: i vissa fall måste de deklareras, i andra inte (vilket betyder att typerna är antagna ändå).

Alexey Naidenov. ITooLabs. Utvecklingsfall på Go (Golang) telefonplattform. Del 1

Det kan ses att det är på modet att beskriva strukturer. Det kan ses att vi har konceptet med en pekare (där asterisken är). Det kan ses att det finns särskilt stöd för att deklarera initiering av arrayer och associativa arrayer.

Ungefär förståeligt - man kan leva. Försöker skriva Hej världen:

Alexey Naidenov. ITooLabs. Utvecklingsfall på Go (Golang) telefonplattform. Del 1

Vad ser vi? Detta är C-liknande syntax, semikolon är valfritt. Det kan vara en separator för två linjer, men bara om det är två konstruktioner som är exakt på samma linje.

Vi ser att parenteserna i kontrollstrukturerna (på den 14:e raden) är valfria, men lockiga krävs alltid. Vi ser att skrivningen är statisk. Tim visas i de flesta fall. Det här exemplet är något mer komplicerat än det vanliga Hej världen - bara för att visa att det finns ett bibliotek.

Vad mer ser vi viktigt? Koden är organiserad i paket. Och för att kunna använda paketet i din egen kod måste du importera det med importdirektivet - detta är också viktigt. Vi börjar – det fungerar. Bra!

Låt oss prova något mer komplicerat: Hej världen, men nu är det en http-server. Vad ser vi intressant här?

Alexey Naidenov. ITooLabs. Utvecklingsfall på Go (Golang) telefonplattform. Del 1

Först fungerar funktionen som en parameter. Det betyder att funktionen vi har är en ”förstklassig medborgare” och man kan göra mycket intressant med den i funktionell stil. Vi ser det oväntade nästa: importdirektivet hänvisar direkt till GitHub-förvaret. Just det, så är det – dessutom är det så det ska göras.

I Go är ett pakets universella identifierare webbadressen till dess arkiv. Det finns ett speciellt Goget-verktyg som går till alla beroenden, laddar ner dem, installerar dem, kompilerar dem och förbereder dem för användning vid behov. Samtidigt känner Goget till html-meta. Följaktligen kan du behålla en http-katalog, som kommer att innehålla länkar till ditt specifika arkiv (som vi till exempel gör).

Vad mer ser vi? Http och Json i det vanliga biblioteket. Det finns uppenbarligen introspektion - reflektion, som bör användas vid kodning / json, eftersom vi helt enkelt ersätter det med något godtyckligt objekt.

Vi kör den och ser att vi har 20 rader användbar kod som kompilerar, körs och ger den aktuella genomsnittliga belastningen på maskinen (på maskinen som den körs på).
Vad mer är viktigt av det vi direkt kan se här? Den kompileras till en statisk binär (buinär). Den här binära filen har inga beroenden alls, inga bibliotek! Det kan kopieras till vilket system som helst, körs omedelbart och det kommer att fungera.

Går vidare.

Go: metoder och gränssnitt

Go har metoder. Du kan deklarera en metod för alla anpassade typer. Dessutom är detta inte nödvändigtvis en struktur, utan kan vara ett alias av någon typ. Du kan deklarera ett alias för N32 och skriva metoder för att det ska göra något användbart.

Och det är här vi faller i en dvala för första gången ... Det visar sig att Go inte har klasser som sådana. De som känner till Go kanske säger att det finns typinkludering, men det här är helt annorlunda. Ju tidigare utvecklaren slutar se det som arv, desto bättre. Det finns inga klasser i Go, och det finns inget arv heller.

Fråga! Vad gav företaget av författare ledda av Google oss för att visa världens komplexitet? Vi har fått gränssnitt!

Alexey Naidenov. ITooLabs. Utvecklingsfall på Go (Golang) telefonplattform. Del 1

Ett gränssnitt är en speciell typ som låter dig skriva enkla metoder, metodsignaturer. Vidare kommer alla typer för vilka dessa metoder finns (exekveras) att motsvara detta gränssnitt. Det betyder att du helt enkelt kan skriva motsvarande funktion för en typ, för en annan (vilket motsvarar den gränssnittstypen). Deklarera sedan en variabel av typen av detta gränssnitt och tilldela något av dessa objekt till den.

För hardcore-fans kan jag säga att denna variabel faktiskt kommer att innehålla två pekare: en till data, den andra till en speciell deskriptortabell som är specifik för just denna typ, till gränssnittet av denna typ. Det vill säga, kompilatorn gör sådana tabeller med deskriptorer vid tidpunkten för länkningen.

Och det finns naturligtvis pekare att ta bort i Go. Ordet gränssnitt {} (med två lockiga klammerparenteser) är en variabel som gör att du i princip kan peka på vilket objekt som helst.
Än så länge är allt i sin ordning, allt är bekant. Inget förvånande.

Gå: goroutiner

Nu kommer vi till det vi är intresserade av: lättviktsprocesser - goroutiner (goroutiner) i Go-terminologi.

Alexey Naidenov. ITooLabs. Utvecklingsfall på Go (Golang) telefonplattform. Del 1

  1. För det första är de riktigt lätta (mindre än 2 Kb).
  2. För det andra är kostnaden för att skapa en sådan goroutin försumbar: du kan skapa tusen av dem per sekund - ingenting kommer att hända.
  3. De betjänas av sin egen schemaläggare, som helt enkelt överför kontrollen från en goroutin till en annan.
  4. I detta fall överförs kontrollen i följande fall:
    • om en go-sats påträffas (om goroutinen startar nästa goroutine);
    • om ett blockerande in-/utsamtal är aktiverat;
    • om sophämtning utlöses;
    • om någon operation med kanaler startas.

Det vill säga, närhelst ett Go-program körs på en dator, upptäcker det antalet kärnor i systemet, startar så många trådar som behövs (hur många kärnor finns i systemet, eller hur många du sa till det). Följaktligen kommer schemaläggaren att köra dessa lätta exekveringstrådar på alla dessa operativsystemtrådar i varje kärna.

Det bör noteras att detta är det mest effektiva sättet att använda järn. Utöver det vi har visat gör vi mycket mer. Vi tillverkar till exempel DPI-system som tillåter servering av 40 gigabit i en enhet (beroende på vad som händer i dessa rader).

Där, även innan Go, använde vi exakt samma schema av just denna anledning: eftersom det låter dig spara processorcachens lokalitet, minska antalet OS-kontextväxlar avsevärt (vilket också tar mycket lång tid). Jag upprepar: detta är det mest effektiva sättet att använda järn.

Detta enkla exempel på 21 rader är ett exempel som helt enkelt gör ekoserver. Observera samtidigt att servefunktionen är extremt enkel, den är linjär. Det finns inga återuppringningar, ingen anledning att bry sig och tänka... Du bara läser och skriver!

Samtidigt, om du läser och skriver, borde den faktiskt blockera - den här goroutinen ställs helt enkelt i kö och tas av schemaläggaren när exekvering blir möjlig igen. Det vill säga, denna enkla kod kan fungera som en ekoserver för så många anslutningar som operativsystemet på den här maskinen tillåter.

Fortsättning snart...

Några annonser 🙂

Tack för att du stannar hos oss. Gillar du våra artiklar? Vill du se mer intressant innehåll? Stöd oss ​​genom att lägga en beställning eller rekommendera till vänner, moln VPS för utvecklare från $4.99, en unik analog av ingångsservrar, som uppfanns av oss för dig: Hela sanningen om VPS (KVM) E5-2697 v3 (6 kärnor) 10GB DDR4 480GB SSD 1Gbps från $19 eller hur delar man en server? (tillgänglig med RAID1 och RAID10, upp till 24 kärnor och upp till 40 GB DDR4).

Dell R730xd 2 gånger billigare i Equinix Tier IV datacenter i Amsterdam? Bara här 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV från $199 i Nederländerna! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - från $99! Läs om Hur man bygger infrastructure corp. klass med användning av Dell R730xd E5-2650 v4-servrar värda 9000 XNUMX euro för en slant?

Källa: will.com

Lägg en kommentar