Aleksei Naydenov. ITooLabs. Go (Golang) telefoniplatvormi arendamise juhtum. 1. osa

Aleksei Naydenov, tegevjuht ITooLabs, räägib Go (Golang) programmeerimiskeeles telekommunikatsioonioperaatoritele mõeldud telekommunikatsiooniplatvormi arendamisest. Aleksei jagab ka oma kogemusi platvormi juurutamisel ja käitamisel ühes Aasia suurimas telekommunikatsioonioperaatoris, mis kasutas platvormi kõnepostiteenuste (VoiceMail) ja virtuaalse PBX (Cloud PBX) pakkumiseks.

Aleksei Naydenov. ITooLabs. Go (Golang) telefoniplatvormi arendamise juhtum. 1. osa

Aleksei Naydenov (edaspidi – AN): - Tere kõigile! Minu nimi on Aleksei Naydenov. Olen ITooLabsi direktor. Kõigepealt tahaksin vastata, millega ma siin tegelen ja kuidas ma siia sattusin.

Kui vaatate Bitrix24 Marketplace'i (jaotis "Telefoonia"), siis 14 rakendust ja 36 seal olevat rakendust (40%) oleme meie:

Aleksei Naydenov. ITooLabs. Go (Golang) telefoniplatvormi arendamise juhtum. 1. osa

Täpsemalt on need meie operaatorpartnerid, kuid kõige selle taga on meie platvorm (Platform as a Service) – see, mida me neile väikese sendi eest müüme. Tegelikult tahaksin rääkida selle platvormi arengust ja sellest, kuidas me Go-ni jõudsime.

Nüüd on meie platvormi numbrid:

Aleksei Naydenov. ITooLabs. Go (Golang) telefoniplatvormi arendamise juhtum. 1. osa

44 operaatoripartnerit, sealhulgas Megafon. Üldiselt meeldib meile väga erinevatel seiklustel käia ja meil on reaalne juurdepääs 100 operaatori 44 miljonile abonendile siin Venemaal. Seega, kui kellelgi on äriideid, siis kuulame neid alati hea meelega.

  • 5000 kasutajaettevõtet.
  • Kokku 20 000 tellijat. See kõik on b2b – teeme koostööd ainult ettevõtetega.
  • Päeva jooksul 300 kõnet minutis.
  • 100 miljonit kõneminutit eelmisel aastal (me tähistasime). See ei võta arvesse siseläbirääkimisi, mis on saadaval meie platvormil.

Kuidas see alguse sai?

Kuidas õiged kutid üldse oma platvormi tegema hakkavad? Peame arvestama ka sellega, et meil on “hardcore ettevõtte” arenduslugu ja seda isegi ettevõtte jaoks kõige täpsemal aastaajal! See oli õnnelik aeg, kui tulete kliendi juurde ja ütlete: "Meil on vaja veel paar serverit." Ja klient: “Pole küsimustki! Meil on riiulis kümme."

Nii et me tegime Oracle'i, Java, WebSphere'i, Db2 ja kõike muud. Seetõttu võtsime loomulikult parimad tarnijalahendused, integreerisime need ja proovisime sellega hakkama saada. Kõndisime omapäi. See oleks selline sisemine käivitamine.

See kõik sai tegelikult alguse 2009. aastal. Alates 2006. aastast oleme nii või teisiti operaatorilahendustega tihedalt seotud. Tegime mitu kohandatud virtuaalset PBX-i (nagu see, mis meil praegu on tellitud): vaatasime seda, otsustasime, et see on hea, ja otsustasime alustada sisemist käivitamist.

Aleksei Naydenov. ITooLabs. Go (Golang) telefoniplatvormi arendamise juhtum. 1. osa

Võtsime VMWare. Kuna olime omapead, pidime kohe hülgama laheda müüja Storage’i. Me teame nende kohta kõike: lubadused tuleb jagada 3-ga ja maksumus korrutada 10-ga. Sellepärast tegid nad DirDB ja nii edasi.

Siis hakkas see kasvama. Sellele lisandus arveldusteenus, kuna platvorm ei saanud enam hakkama. Seejärel kolis MySQL-i arveldusserver Mongosse. Selle tulemusena saime toimiva lahenduse, mis töötleb kõiki sinna tulevaid kõnesid:

Aleksei Naydenov. ITooLabs. Go (Golang) telefoniplatvormi arendamise juhtum. 1. osa

Kuid kuskil sees keerleb seesama müüja toode – peamine, tuumatoode, mille me kunagi võtsime. Umbes 2011. aasta lõpus saime aru, et meie peamine kitsaskoht on loomulikult see konkreetne toode – me jookseksime sellega kokku. Nägime enda ees seina, kuhu jooksime täiega sisse, kuna kliente tuli aina juurde.
Seetõttu pidime midagi ette võtma. Loomulikult tegime erinevate toodete kohta üsna palju uuringuid – nii avatud lähtekoodiga kui ka hankijate oma. Ma ei hakka sellel praegu pikemalt peatuma – see pole see, millest me räägime. Viimane tagavaravariant, mille peale mõtlesime, oli teha oma platvorm.

Lõpuks jõudsime selle variandini. Miks? Kuna kõik müüja- ja avatud lähtekoodiga tooted on loodud 10 aastat vanade probleemide lahendamiseks. Noh, kui 10 aastat vana ja veel mõned! Valik sai meile selgeks: kas jätame hüvasti oma suurepärase ideega ideaalsest teenusest (partneritele, operaatoritele ja endale) või teeme midagi omaette.

Otsustasime midagi omaette teha!

Platvormi nõuded

Kui olete midagi pikka aega teinud (kasutanud kellegi teise toodet), siis tekib teie peas aeglaselt mõte: kuidas ma seda ise teeksin? Kuna oleme ettevõttes kõik programmeerijad (välja arvatud müügimehed, mitteprogrammeerijaid pole olemas), kujunesid meie nõuded välja juba ammu ja need olid selged:

  1. Kõrge arengukiirus. Meid piinanud müüja toode ei rahuldanud esiteks seetõttu, et kõik osutus pikaks ja aeglaselt. Tahtsime seda kiiresti – meil oli palju ideid! Ideid on meil veel palju, aga siis oli ideede nimekiri selline, et tundus kümme aastat ette. Nüüd vaid aastaks.
  2. Mitmetuumalise raua maksimaalne kasutamine. See oli ka meie jaoks oluline, kuna nägime, et südamikke tuleb ainult rohkem ja rohkem.
  3. Kõrge töökindlus. Midagi, millega me ka nutsime.
  4. Kõrge vastupidavus tõrgetele.
  5. Tahtsime lõpetada igapäevaste väljaannete protsessiga. Selleks oli meil vaja keelevalikut.

Aleksei Naydenov. ITooLabs. Go (Golang) telefoniplatvormi arendamise juhtum. 1. osa

Sellest lähtuvalt kasvavad selgelt loogiliselt välja nõuded tootele, mille oleme endale seadnud.

  1. Kui tahame tuge mitmetuumalistele süsteemidele, siis vajame tuge paralleelkäituseks.
  2. Kui vajame arenduskiirust, siis vajame konkurentsivõimelist arengut toetavat keelt, konkurentsivõimelist programmeerimist. Kui keegi pole erinevusega kokku puutunud, on see väga lihtne:
    • Paralleelprogrammeerimine on seotud kahe erineva lõimega erinevatel tuumadel;
    • Samaaegne täitmine või täpsemalt samaaegsuse tugi seisneb selles, kuidas keel (või käitusaeg, see pole oluline) aitab varjata kogu paralleelkäivitamisest tulenevat keerukust.
  3. Kõrge stabiilsus. Ilmselgelt vajasime klastrit ja paremat, kui meil oli müüja tootel.

Aleksei Naydenov. ITooLabs. Go (Golang) telefoniplatvormi arendamise juhtum. 1. osa

Meil polnud tegelikult nii palju valikuvõimalusi, kui mäletate. Esiteks Erlang – me armastame ja teame seda, see oli minu isiklik lemmik. Teiseks pole Java isegi mitte Java, vaid konkreetselt Scala. Kolmandaks keel, mida me tol ajal üldse ei osanud – Mine. See oli siis just ilmunud või õigemini eksisteerinud juba umbes kaks aastat, kuid polnud veel välja antud.

Mine võitis!

Go ajalugu

Tegime sellele platvormi. Püüan selgitada, miks.

Go lühiajalugu. See sai alguse 2007. aastal, avati 2009. aastal, esimene versioon ilmus 2012. aastal (ehk siis alustasime tööd juba enne esimest väljalaset). Algataja oli Google, kes tahtis, nagu ma kahtlustan, Java välja vahetada.

Autorid on väga kuulsad:

  • Ken Thomson, kes oli Unixi taga, leiutas UTF-8, töötas Plan 9 süsteemi kallal;
  • Rob Pike, kes leiutas koos Keniga UTF-8, töötas ka Bell Labsi plaani 9, Inferno, Limbo kallal;
  • Robert Giesmer, keda me teame ja armastame Java HotSpoti kompilaatori leiutamise ja V8 generaatori (Google'i Javascripti tõlk) loomise eest;
  • Ja üle 700 kaastöölise, sealhulgas mõned meie paigad.

Aleksei Naydenov. ITooLabs. Go (Golang) telefoniplatvormi arendamise juhtum. 1. osa

Mine: esimene pilk

Näeme, et keel on enam-vähem lihtne ja arusaadav. Meil on selged tüübid: mõnel juhul tuleb need deklareerida, mõnel juhul pole need vajalikud (see tähendab, et tüübid järeldatakse nii või teisiti).

Aleksei Naydenov. ITooLabs. Go (Golang) telefoniplatvormi arendamise juhtum. 1. osa

On näha, et moes on struktuure kirjeldada. On näha, et meil on kursori mõiste (kus on tärn). On näha, et massiivide ja assotsiatiivsete massiivide initsialiseerimise deklareerimine on olemas.

See on peaaegu selge - sa saad elada. Proovime kirjutada Tere, maailm:

Aleksei Naydenov. ITooLabs. Go (Golang) telefoniplatvormi arendamise juhtum. 1. osa

Mida me näeme? See on C-tüüpi süntaks, semikoolon on valikuline. See võib olla kahe rea eraldaja, kuid ainult siis, kui need on kaks konstruktsiooni, mis asuvad samal real.

Näeme, et sulud juhtstruktuurides (14. real) on valikulised, kuid lokkis traksid on alati vajalikud. Näeme, et tippimine on staatiline. Timi võetakse enamasti välja. See näide on veidi keerulisem kui tavaline Tere, maailm – lihtsalt näitamaks, et raamatukogu on olemas.

Mida me veel olulisena näeme? Kood on jaotatud pakettidena. Ja selleks, et kasutada paketti oma koodis, peate selle importima impordidirektiivi abil - see on samuti oluline. Käivitame selle – see töötab. Suurepärane!

Proovime järgmiseks midagi keerulisemat: Tere, maailm, aga alles nüüd on see http-server. Mida huvitavat me siin näeme?

Aleksei Naydenov. ITooLabs. Go (Golang) telefoniplatvormi arendamise juhtum. 1. osa

Esiteks toimib funktsioon parameetrina. See tähendab, et meie funktsioon on “esimese klassi kodanik” ja sellega saab funktsionaalses stiilis palju huvitavat teha. Järgmisena näeme midagi ootamatut: impordidirektiiv lingib otse GitHubi hoidlaga. Täpselt nii, nii see on – pealegi nii tulebki teha.

Go-s on paketi universaalseks identifikaatoriks selle hoidla URL. On olemas spetsiaalne Gogeti utiliit, mis tõmbab kõik sõltuvused, laadib need alla, installib, kompileerib ja vajadusel valmistab kasutamiseks ette. Samal ajal teab Goget html-meta. Sellest lähtuvalt saate hoida http kataloogi, mis sisaldab linke teie konkreetsele hoidlale (nagu meie näiteks teeme).

Mida me veel näeme? Http ja Json standardses teegis. Ilmselgelt on olemas sisekaemus – refleksioon, mida tuleks kasutada kodeerimisel/json-is, kuna me lihtsalt asendame selle mingi suvalise objekti.

Käitame selle ja näeme, et meil on 20-realine kasulik kood, mis kompileerib, käivitab ja raporteerib masina hetke keskmise koormuse (masinal, millel see käivitatakse).
Mis on veel oluline, mida siin kohe näha saame? See on koostatud üheks staatiliseks kahendfailiks (buinary). Sellel kahendfailil pole üldse sõltuvusi ega teeke! Saate selle kopeerida mis tahes süsteemi, käivitada see kohe ja see töötab.

Edasi liikumine.

Mine: meetodid ja liidesed

Go on meetodid. Saate deklareerida meetodi mis tahes kohandatud tüübi jaoks. Pealegi pole see tingimata struktuur, vaid võib-olla teatud tüüpi varjunimi. Saate deklareerida N32 pseudonüümi ja kirjutada meetodeid, et see saaks midagi kasulikku teha.

Ja siin langeme esimest korda stuuporisse... Selgub, et Go-l ei olegi tunde kui selliseid. Need, kes tunnevad Go’t, võivad öelda, et on olemas tüübi kaasamine, aga see on hoopis midagi muud. Mida varem arendaja lõpetab selle pärandina mõtlemise, seda parem. Go-s pole klasse ega ka pärandit.

küsimus! Mida on Google’i juhitud autorite seltskond meile andnud, et peegeldada maailma keerukust? Nad andsid meile liidesed!

Aleksei Naydenov. ITooLabs. Go (Golang) telefoniplatvormi arendamise juhtum. 1. osa

Liides on eritüüp, mis võimaldab kirjutada lihtsalt meetodeid, meetodisignatuure. Lisaks vastavad sellele liidesele kõik tüübid, mille jaoks need meetodid on olemas (käitatakse). See tähendab, et saate lihtsalt kirjeldada vastavat funktsiooni ühe tüübi jaoks, teise jaoks (mis vastab sellele liidese tüübile). Järgmisena deklareerige selle liidese tüüpi muutuja ja määrake sellele mõni neist objektidest.

Kõvakujuliste fännide jaoks võin öelda, et sellel muutujal on tegelikult kaks viidet: üks andmetele ja teine ​​spetsiaalsele deskriptorite tabelile, mis on selle konkreetse tüübi jaoks tüüpiline seda tüüpi liidese jaoks. See tähendab, et kompilaator loob linkimise ajal sellised deskriptorite tabelid.

Ja Go-s on muidugi viiteid tühiseks. Sõnaliides {} (kahe sulgsuluga) on muutuja, mis võimaldab põhimõtteliselt osutada mis tahes objektile.
Siiani on kõik hästi, kõik on tuttav. Ei midagi üllatavat.

Mine: gorutiinid

Nüüd jõuame selleni, mis meid huvitab: kerged protsessid – go-terminoloogias gorutiinid (gorutiinid).

Aleksei Naydenov. ITooLabs. Go (Golang) telefoniplatvormi arendamise juhtum. 1. osa

  1. Esiteks on need väga kerged (alla 2 KB).
  2. Teiseks on sellise gorutiini loomise kulud tühised: saate neid luua tuhat sekundis - midagi ei juhtu.
  3. Neid teenindab nende oma ajakava, mis lihtsalt annab juhtimise ühelt gorutiinilt teisele.
  4. Sel juhul antakse juhtimine üle järgmistel juhtudel:
    • kui kohtatakse avaldist mine (kui gorutiin alustab järgmist gorutiinit);
    • kui blokeeriv sisend/väljundkõne on lubatud;
    • kui algab prügivedu;
    • kui käivitatakse mõni toiming kanalitega.

See tähendab, et iga kord, kui Go programm arvutis töötab, määrab see süsteemi tuumade arvu, käivitab nii palju lõime kui vaja (mitu südamikku süsteemis on või kui palju te seda ütlesite). Sellest lähtuvalt käivitab planeerija neid kergeid täitmislõime kõigis nendes operatsioonisüsteemi lõimedes igas tuumas.

Tuleb märkida, et see on kõige tõhusam viis raua kasutamiseks. Lisaks näidatule teeme palju muudki. Valmistame näiteks DPI-süsteeme, mis võimaldavad ühel seadmel teenindada 40 gigabitti (olenevalt sellest, mis neil ridadel toimub).

Seal kasutasime isegi enne Go-d täpselt sama skeemi just sel põhjusel: kuna see võimaldab meil säilitada protsessori vahemälu asukohta ja oluliselt vähendada OS-i kontekstilülitite arvu (mis võtab samuti palju aega). Kordan: see on kõige tõhusam viis raua kasutamiseks.

See lihtne 21-realine näide on näide, mis lihtsalt teeb kajaserverit. Pange tähele, et serveerimisfunktsioon on äärmiselt lihtne, see on lineaarne. Ei ole tagasihelistamisi, pole vaja vaeva näha ja mõelda... Sa lihtsalt loed ja kirjutad!

Samas, kui loete ja kirjutate, peaks see tegelikult blokeerima - see gorutiin pannakse lihtsalt järjekorda ja planeerija võtab selle, kui täitmine taas võimalikuks muutub. See tähendab, et see lihtne kood võib toimida kajaserverina nii paljude ühenduste jaoks, kui selle masina operatsioonisüsteem seda võimaldab.

Jätkub peagi...

Mõned reklaamid 🙂

Täname, et jäite meiega. Kas teile meeldivad meie artiklid? Kas soovite näha huvitavamat sisu? Toeta meid, esitades tellimuse või soovitades sõpradele, pilve VPS arendajatele alates 4.99 dollarist, algtaseme serverite ainulaadne analoog, mille me teie jaoks leiutasime: Kogu tõde VPS (KVM) E5-2697 v3 (6 tuuma) 10GB DDR4 480GB SSD 1Gbps kohta alates 19 dollarist või kuidas serverit jagada? (saadaval RAID1 ja RAID10, kuni 24 tuuma ja kuni 40 GB DDR4-ga).

Dell R730xd 2x odavam Amsterdami Equinixi Tier IV andmekeskuses? Ainult siin 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6 GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 telerit alates 199 dollarist Hollandis! Dell R420 – 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB – alates 99 dollarist! Millegi kohta lugema Kuidas ehitada infrastruktuuri ettevõtet. klassis koos Dell R730xd E5-2650 v4 serverite kasutusega 9000 eurot senti?

Allikas: www.habr.com

Lisa kommentaar