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

Alexey Naidenov, administrerende direktør ITooLabs, snakker om utviklingen av en telekommunikasjonsplattform for teleoperatører i programmeringsspråket Go (Golang). Alexey deler også sin erfaring med å distribuere og drifte plattformen i en av de største asiatiske telekomoperatørene, som brukte plattformen til å tilby taleposttjenester (VoiceMail) og Virtual PBX (Cloud PBX).

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

Alexey Naydenov (heretter - AN): - Hei alle sammen! Mitt navn er Alexey Naidenov. Jeg er direktør for ITooLabs. Først av alt vil jeg gjerne svare på hva jeg gjør her og hvordan jeg havnet her.

Hvis du ser på Bitrix24 Marketplace (seksjonen "Telefoni"), så er 14 applikasjoner og 36 som er der (40%) oss:

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

Mer presist er dette våre partneroperatører, men bak alt dette ligger plattformen vår (Platform as a Service) – det vi selger til dem for en liten slant. Egentlig vil jeg snakke om utviklingen av denne plattformen og hvordan vi kom til Go.

Tallene for plattformen vår er nå:

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

44 partneroperatører, inkludert MegaFon. Generelt sett elsker vi å dra på eventyr, og vi har faktisk tilgang til 100 millioner abonnenter av 44 operatører her i Russland. Derfor, hvis noen har noen forretningsideer, er vi alltid glade for å lytte til dem.

  • 5000 brukerbedrifter.
  • 20 000 abonnenter totalt. Alt er b2b - vi jobber kun med selskaper.
  • 300 samtaler i minuttet i løpet av dagen.
  • 100 millioner ringeminutter i fjor (vi feiret). Dette uten å ta hensyn til de interne forhandlingene som er på vår plattform.

Hvordan startet det?

Hvordan begynner de rette karene å lage sin egen plattform? Vi må også ta i betraktning at vi har hatt en historie med "hardcore enterprise"-utvikling, og til og med på den mest nøyaktige tiden av året for en bedrift! Det var den lykkelige tiden når du kommer til kunden og sier: "Vi trenger et par servere til." Og kunden: «Ja, ingen tvil! Vi har en tier i stativet.

Så vi gjorde Oracle, Java, WebSphere, Db2 og alt det der. Derfor tok vi selvfølgelig de beste leverandørløsningene, integrerte dem og prøvde å ta av med det. De spilte på egenhånd. Det ville vært en slik intern oppstart.

Det hele startet i 2009. Siden 2006 har vi vært tett involvert i operatørbeslutninger, på en eller annen måte. Vi laget flere tilpassede virtuelle PBX-er (som det vi nå har på bestilling): vi så, bestemte oss for at det var bra, og bestemte oss for å sette i gang en intern oppstart.

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

Ta VMWare. Siden vi gikk på egenhånd, måtte vi umiddelbart forlate den kule leverandøren Storage. Vi vet alt om dem: at løfter skal deles på 3, og kostnadene skal multipliseres med 10. Derfor gjorde vi DirDB og så videre.

Så begynte det å gro. Faktureringstjenesten ble lagt til dette, fordi plattformen ikke orket lenger. Deretter flyttet faktureringsserveren fra MySQL til Mongo. Som et resultat fikk vi en fungerende løsning som behandler alle anropene som går dit:

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

Men et sted inni spinner det samme leverandørproduktet - det viktigste kjernefysiske produktet, som vi en gang tok. Omtrent ved slutten av 2011 innså vi selv at hovedflaskehalsen for oss, selvfølgelig, vil være akkurat dette produktet - vi vil støte på det. Vi så en vegg foran oss, som vi løp inn i full galopp, mens kundene gikk, ble lagt til.
Derfor måtte vi gjøre noe. Selvfølgelig gjorde vi ganske mye research på ulike produkter - både åpen kildekode og leverandør. Jeg skal ikke dvele ved dette nå - det er ikke poenget. Det aller siste alternativet vi tenkte på var å lage vår egen plattform.

Til slutt kom vi til dette alternativet. Hvorfor? Fordi alle leverandør- og åpen kildekode-produkter ble laget for å løse problemer for 10 år siden. Vel, hvis en 10-åring, og noen flere! Valget har blitt åpenbart for oss: enten sier vi farvel til vår gode idé om en ideell tjeneste (for partnere, operatører og oss selv), eller så gjør vi noe eget.

Vi bestemte oss for å gjøre noe annerledes!

Plattformkrav

Hvis du gjør noe over lang tid (du utnytter andres produkt), så former seg sakte tanken i hodet ditt: hvordan ville jeg gjort det selv? Siden vi alle er programmerere i selskapet (bortsett fra selgere, det er ingen ikke-programmerere), har kravene våre blitt dannet i lang tid, og de var klare:

  1. Høy utviklingshastighet. Leverandørens produkt, som plaget oss, passet ikke oss i utgangspunktet fordi alt fungerte i lang tid og sakte. Vi ville raskt – vi hadde mange ideer! Vi har fortsatt mange ideer, men så var idélisten slik at det virket som ti år frem i tid. Nå bare i ett år.
  2. Maksimal utnyttelse av flerkjernejern. Dette var også viktig for oss, for vi så at det bare kom til å bli flere og flere kjerner.
  3. Høy pålitelighet. Den vi gråt også.
  4. Høy feiltoleranse.
  5. Vi ønsket å ende opp med en daglig utgivelsesprosess. For å gjøre dette trengte vi et språkvalg.

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

Følgelig, fra kravene til produktet som vi har presentert for oss selv, vokser kravene til språket på en klart logisk måte.

  1. Hvis vi ønsker støtte for flerkjernesystemer, så trenger vi støtte for parallell utførelse.
  2. Hvis vi trenger utviklingshastighet, trenger vi et språk som støtter konkurransedyktig utvikling, konkurransedyktig programmering. Hvis noen ikke har støtt på forskjellen, så er det veldig enkelt:
    • parallell programmering handler om hvordan to forskjellige tråder går på forskjellige kjerner;
    • samtidig kjøring, mer spesifikt samtidighetsstøtte, handler om hvordan språket (eller kjøretiden, uansett) hjelper til med å skjule all kompleksiteten som kommer fra parallell kjøring.
  3. Høy stabilitet. Selvfølgelig trengte vi en klynge, og den var bedre enn det vi hadde på leverandørproduktet.

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

Vi hadde egentlig ikke så mange alternativer, hvis du husker. For det første, Erlang - vi elsker det og vet det, det var min personlige, personlige favoritt. For det andre er Java ikke engang Java, men spesifikt Scala. For det tredje språket som vi på den tiden ikke kunne i det hele tatt - Gå. Den hadde nettopp dukket opp da, mer presist, den hadde allerede eksistert i omtrent to år, men var ennå ikke utgitt.

Beseiret Go!

Historien til Go

Vi laget en plattform på den. Jeg skal prøve å forklare hvorfor.

En kort historie om Go. Startet i 2007, åpnet i 2009, den første versjonen ble utgitt i 2012 (det vil si at vi begynte å jobbe allerede før den første utgivelsen). Initiativtakeren var Google, som ønsket å erstatte, som jeg mistenker, Java.

Forfatterne er veldig kjente:

  • Ken Thomson, som sto bak Unix, oppfant UTF-8, jobbet med Plan 9-systemet;
  • Rob Pike, som designet UTF-8 med Ken, jobbet også med Plan 9, Inferno, Limbo på Bell Labs;
  • Robert Gizmer, som vi kjenner og elsker for å ha oppfunnet Java HotSpot Compiler og for å jobbe med generatoren i V8 (Googles Javascript-tolk);
  • Og over 700 bidragsytere, inkludert noen av patchene våre.

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

Gå med et blikk

Vi ser at språket er mer eller mindre enkelt og forståelig. Vi har åpenbare typer: i noen tilfeller må de deklareres, i andre gjør de det ikke (som betyr at typene er utledet uansett).

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

Det kan sees at det er mote å beskrive strukturer. Det kan sees at vi har konseptet med en peker (der stjernen er). Det kan sees at det er spesiell støtte for å deklarere initialisering av arrays og assosiative arrays.

Omtrent forståelig - du kan leve. Prøver å skrive Hei, verden:

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

Hva ser vi? Dette er C-lignende syntaks, semikolon er valgfritt. Det kan være en skilletegn for to linjer, men bare hvis dette er to konstruksjoner som er nøyaktig på samme linje.

Vi ser at parentesene i kontrollstrukturene (på 14. linje) er valgfrie, men krøllete er alltid påkrevd. Vi ser at skrivingen er statisk. Tim vises i de fleste tilfeller. Dette eksemplet er litt mer komplisert enn den vanlige Hei, verden - bare for å vise at det finnes et bibliotek.

Hva annet ser vi viktig? Koden er organisert i pakker. Og for å bruke pakken i din egen kode, må du importere den ved å bruke importdirektivet - dette er også viktig. Vi starter - det fungerer. Flott!

La oss prøve noe mer komplisert: Hei verden, men nå er det en http-server. Hva ser vi interessant her?

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

For det første fungerer funksjonen som en parameter. Dette betyr at funksjonen vi har er en "førsteklasses borger" og du kan gjøre mye interessant med den i en funksjonell stil. Vi ser det uventede neste: importdirektivet refererer direkte til GitHub-depotet. Det stemmer, sånn er det – dessuten er det slik det skal gjøres.

I Go er en pakkes universelle identifikator nettadressen til depotet. Det er et spesielt Goget-verktøy som går for alle avhengighetene, laster dem ned, installerer dem, kompilerer dem og forbereder dem til bruk om nødvendig. Samtidig vet Goget om html-meta. Følgelig kan du beholde en http-katalog, som vil inneholde lenker til ditt spesifikke depot (som vi for eksempel gjør).

Hva mer ser vi? Http og Json i det vanlige biblioteket. Det er åpenbart introspeksjon - refleksjon, som bør brukes i koding / json, fordi vi ganske enkelt erstatter et vilkårlig objekt med det.

Vi kjører den og ser at vi har 20 linjer med nyttig kode som kompilerer, kjører og gir gjeldende gjennomsnittsbelastning på maskinen (på maskinen den kjører på).
Hva annet er viktig av det vi umiddelbart kan se her? Den kompileres til en statisk binær (buinær). Denne binære filen har ingen avhengigheter i det hele tatt, ingen biblioteker! Det kan kopieres til et hvilket som helst system, kjør umiddelbart, og det vil fungere.

Flytte på.

Go: metoder og grensesnitt

Go har metoder. Du kan deklarere en metode for enhver egendefinert type. Dessuten er dette ikke nødvendigvis en struktur, men kan være et alias av en eller annen type. Du kan erklære et alias for N32 og skrive metoder for at den skal gjøre noe nyttig.

Og det er her vi faller i stupor for første gang ... Det viser seg at Go ikke har klasser som sådan. De som kjenner Go kan si at det er typeinkludering, men dette er en helt annen. Jo før utvikleren slutter å tenke på det som arv, jo bedre. Det er ingen klasser i Go, og det er ingen arv heller.

Spørsmål! Hva ga selskapet av forfattere ledet av Google oss for å vise kompleksiteten i verden? Vi har fått grensesnitt!

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

Et grensesnitt er en spesiell type som lar deg skrive enkle metoder, metodesignaturer. Videre vil enhver type som disse metodene eksisterer for (utføres) tilsvare dette grensesnittet. Dette betyr at du ganske enkelt kan skrive den tilsvarende funksjonen for en type, for en annen (som tilsvarer den grensesnitttypen). Deretter erklærer du en variabel av typen til dette grensesnittet og tilordner noen av disse objektene til den.

For hardcore-fans kan jeg si at denne variabelen faktisk vil inneholde to pekere: en til data, den andre til en spesiell deskriptortabell som er spesifikk for denne typen, til grensesnittet til denne typen. Det vil si at kompilatoren lager slike tabeller med beskrivelser på tidspunktet for kobling.

Og det er selvfølgelig pekepinner for å annullere i Go. Ordet grensesnitt {} (med to krøllete klammeparenteser) er en variabel som lar deg peke på ethvert objekt i det hele tatt i prinsippet.
Så langt er alt i orden, alt er kjent. Ikke noe overraskende.

Gå: goroutiner

Nå kommer vi til det vi er interessert i: lettvektsprosesser - goroutiner (goroutiner) i Go-terminologi.

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

  1. For det første er de veldig lette (mindre enn 2 Kb).
  2. For det andre er kostnadene ved å lage en slik gorutine ubetydelige: du kan lage tusen av dem per sekund - ingenting vil skje.
  3. De betjenes av sin egen planlegger, som ganske enkelt overfører kontrollen fra en goroutine til en annen.
  4. I dette tilfellet overføres kontrollen i følgende tilfeller:
    • hvis en go-setning blir møtt (hvis goroutinen starter neste goroutine);
    • hvis et blokkerende inn-/ut-anrop er aktivert;
    • hvis søppelinnsamling utløses;
    • hvis en operasjon med kanaler startes.

Det vil si at hver gang et Go-program kjøres på en datamaskin, oppdager det antall kjerner i systemet, starter så mange tråder som trengs (hvor mange kjerner er i systemet, eller hvor mange du fortalte det til). Følgelig vil planleggeren kjøre disse lette utførelsestrådene på alle disse operativsystemtrådene i hver kjerne.

Det skal bemerkes at dette er den mest effektive måten å utnytte jern på. I tillegg til det vi har vist, gjør vi mye mer. Vi lager for eksempel DPI-systemer som tillater servering av 40 gigabit i en enhet (avhengig av hva som skjer i disse linjene).

Der, selv før Go, brukte vi nøyaktig det samme opplegget av nettopp denne grunnen: fordi det lar deg lagre lokaliteten til prosessorbufferen, redusere antallet OS-kontekstbrytere betydelig (som også tar veldig lang tid). Jeg gjentar: dette er den mest effektive måten å bruke jern på.

Dette enkle 21-linjers eksempelet er et eksempel som ganske enkelt gjør ekkoserver. Vær samtidig oppmerksom på at servefunksjonen er ekstremt enkel, den er lineær. Det er ingen tilbakeringinger, ingen grunn til å bry seg og tenke... Du bare leser og skriver!

Samtidig, hvis du leser og skriver, bør den faktisk blokkere - denne goroutinen blir ganske enkelt satt i kø og tatt av planleggeren når utførelse blir mulig igjen. Det vil si at denne enkle koden kan fungere som en ekkoserver for så mange tilkoblinger som operativsystemet på denne maskinen tillater.

Fortsettelse snart...

Noen annonser 🙂

Takk for at du bor hos oss. Liker du artiklene våre? Vil du se mer interessant innhold? Støtt oss ved å legge inn en bestilling eller anbefale til venner, cloud VPS for utviklere fra $4.99, en unik analog av entry-level servere, som ble oppfunnet av oss for deg: Hele sannheten om VPS (KVM) E5-2697 v3 (6 kjerner) 10GB DDR4 480GB SSD 1Gbps fra $19 eller hvordan dele en server? (tilgjengelig med RAID1 og RAID10, opptil 24 kjerner og opptil 40 GB DDR4).

Dell R730xd 2x billigere i Equinix Tier IV datasenter i Amsterdam? Bare her 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV fra $199 i Nederland! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - fra $99! Lese om Hvordan bygge infrastruktur corp. klasse med bruk av Dell R730xd E5-2650 v4-servere verdt 9000 euro for en krone?

Kilde: www.habr.com

Legg til en kommentar