Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

Mihail Salosin (v nadaljevanju – MS): - Pozdravljeni vsi skupaj! Moje ime je Michael. Delam kot zaledni razvijalec pri MC2 Software in govoril bom o uporabi Go v zaledju mobilne aplikacije Look+.

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

Ima kdo tukaj rad hokej?

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

Potem je ta aplikacija za vas. Je za Android in iOS in se uporablja za gledanje prenosov različnih športnih dogodkov na spletu in posnetih. Aplikacija vsebuje tudi različne statistike, besedilne oddaje, tabele za konference, turnirje in druge informacije, uporabne za navijače.

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

V aplikaciji je tudi nekaj video trenutkov, tj. lahko si ogledate najpomembnejše trenutke tekem (goli, boji, strelski obračuni itd.). Če ne želite gledati celotne oddaje, si lahko ogledate le najbolj zanimive.

Kaj ste uporabili pri razvoju?

Glavni del je bil napisan v Go. API, s katerim so komunicirali mobilni odjemalci, je bil napisan v Go. V Go je bila napisana tudi storitev za pošiljanje potisnih obvestil na mobilne telefone. Napisati smo morali tudi svoj ORM, o katerem bomo morda nekoč govorili. No, nekaj majhnih storitev je bilo napisanih v Go: spreminjanje velikosti in nalaganje slik za urednike ...

Za zbirko podatkov smo uporabili PostgreSQL. Vmesnik urejevalnika je bil napisan v Ruby on Rails z uporabo dragulja ActiveAdmin. Uvažanje statističnih podatkov iz ponudnika statističnih podatkov je prav tako napisano v Rubyju.

Za teste sistemskega API-ja smo uporabili Python unittest. Memcached se uporablja za dušenje plačilnih klicev API-ja, »Chef« se uporablja za nadzor konfiguracije, Zabbix se uporablja za zbiranje in spremljanje notranje statistike sistema. Graylog2 je za zbiranje dnevnikov, Slate je dokumentacija API-ja za stranke.

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

Izbira protokola

Prva težava, na katero smo naleteli: morali smo izbrati protokol za interakcijo med zaledjem in mobilnimi odjemalci na podlagi naslednjih točk ...

  • Najpomembnejša zahteva: podatki o strankah morajo biti posodobljeni v realnem času. To pomeni, da bi morali vsi, ki trenutno gledajo oddajo, prejemati posodobitve skoraj v trenutku.
  • Za poenostavitev smo predpostavili, da se podatki, ki so sinhronizirani z odjemalci, ne izbrišejo, ampak skrijejo s posebnimi zastavicami.
  • Vse vrste redkih zahtev (kot so statistike, sestave ekip, statistike ekip) se pridobijo z običajnimi zahtevami GET.
  • Poleg tega je moral sistem zlahka podpirati 100 tisoč uporabnikov hkrati.

Na podlagi tega smo imeli dve možnosti protokola:

  1. spletne vtičnice. Nismo pa potrebovali kanalov od odjemalca do strežnika. Posodobitve smo morali samo poslati s strežnika odjemalcu, zato je spletna vtičnica odvečna možnost.
  2. Dogodki, poslani iz strežnika (SSE), so prišli prav! Je čisto preprosta in načeloma zadovolji vse, kar potrebujemo.

Dogodki, poslani s strežnika

Nekaj ​​besed o tem, kako ta stvar deluje ...

Deluje na povezavi http. Odjemalec pošlje zahtevo, strežnik odgovori z Content-Type: text/event-stream in ne prekine povezave z odjemalcem, ampak nadaljuje s pisanjem podatkov v povezavo:

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

Podatki se lahko pošiljajo v obliki, ki je dogovorjena s strankami. V našem primeru smo ga poslali v tej obliki: ime spremenjene strukture (oseba, igralec) je bilo poslano v polje dogodkov, JSON z novimi, spremenjenimi polji za igralca pa v polje podatkov.

Zdaj pa se pogovorimo o tem, kako deluje sama interakcija.

  • Prva stvar, ki jo naredi odjemalec, je ugotoviti, kdaj je bila izvedena zadnja sinhronizacija s storitvijo: pogleda svojo lokalno bazo podatkov in ugotovi datum zadnje spremembe, ki jo je zabeležila.
  • Pošlje zahtevo s tem datumom.
  • V odgovor mu pošljemo vse posodobitve, ki so se zgodile od tega datuma.
  • Po tem vzpostavi povezavo s kanalom v živo in se ne zapre, dokler ne potrebuje teh posodobitev:

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

Pošljemo mu seznam sprememb: če nekdo doseže gol, spremenimo izid tekme, če se poškoduje, tudi to pošljemo sproti. Tako stranke takoj prejmejo posodobljene podatke v viru dogodkov tekme. Občasno, da odjemalec razume, da strežnik ni umrl, da se mu ni nič zgodilo, vsakih 15 sekund pošljemo časovni žig - da ve, da je vse v redu in se ni treba znova povezovati.

Kako poteka povezava v živo?

  • Najprej ustvarimo kanal, v katerega bodo prejete posodobitve v medpomnilniku.
  • Po tem se na ta kanal naročimo na prejemanje posodobitev.
  • Nastavimo pravilno glavo, da stranka ve, da je vse ok.
  • Pošlji prvi ping. Preprosto zabeležimo trenutni časovni žig povezave.
  • Nato beremo iz kanala v zanki, dokler se kanal za posodobitev ne zapre. Kanal občasno prejme trenutni časovni žig ali spremembe, ki jih že pišemo v odprte povezave.

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

Prva težava, na katero smo naleteli, je bila naslednja: za vsako povezavo, odprto z odjemalcem, smo ustvarili časovnik, ki je tiktakal enkrat na 15 sekund – izkazalo se je, da če imamo 6 tisoč odprtih povezav z enim strojem (z enim strežnikom API), 6 ustvarjenih je bilo tisoč časovnikov. To je povzročilo, da stroj ni zdržal zahtevane obremenitve. Težava nam ni bila tako očitna, vendar smo dobili malo pomoči in jo odpravili.

Kot rezultat, zdaj naš ping prihaja iz istega kanala, iz katerega prihaja posodobitev.

V skladu s tem obstaja samo en časovnik, ki tiktaka vsakih 15 sekund.

Tukaj je več pomožnih funkcij - pošiljanje glave, pinga in same strukture. To pomeni, da se ime tabele (oseba, tekma, sezona) in informacije o tem vnosu prenesejo tukaj:

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

Mehanizem za pošiljanje posodobitev

Zdaj pa malo o tem, od kod prihajajo spremembe. Imamo več ljudi, urednikov, ki spremljajo prenos v realnem času. Oni ustvarjajo vse dogodke: nekdo je bil izključen, nekdo poškodovan, kakšna zamenjava ...

Z uporabo CMS podatki vstopajo v bazo podatkov. Po tem baza podatkov o tem obvesti strežnike API z uporabo mehanizma Listen/Notify. Strežniki API te informacije že pošiljajo strankam. Tako imamo v bistvu na bazo povezanih le nekaj strežnikov in ni posebne obremenitve baze, saj odjemalec na noben način ne komunicira neposredno z bazo:

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

PostgreSQL: poslušaj/obvesti

Mehanizem Listen/Notify v Postgresu vam omogoča, da naročnike na dogodke obvestite, da se je nek dogodek spremenil – v bazi je bil ustvarjen nek zapis. Da bi to naredili, smo napisali preprost sprožilec in funkcijo:

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

Ko vstavljamo ali spreminjamo zapis, pokličemo funkcijo obvestila na kanalu data_updates, ki ji posreduje ime tabele in identifikator zapisa, ki je bil spremenjen ali vstavljen.

Za vse tabele, ki morajo biti sinhronizirane z odjemalcem, definiramo prožilec, ki po spremembi/posodabljanju zapisa pokliče funkcijo, ki je navedena na spodnjem prosojniku.
Kako se API naroči na te spremembe?

Ustvari se mehanizem Fanout - pošilja sporočila odjemalcu. Zbira vse kanale strank in pošilja posodobitve, ki jih je prejel prek teh kanalov:

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

Tukaj standardna knjižnica pq, ki se poveže z bazo in pove, da želi poslušati kanal (data_updates), preveri, ali je povezava odprta in je vse v redu. Izpuščam preverjanje napak, da prihranim prostor (nepreverjanje je nevarno).

Nato asinhrono nastavimo Ticker, ki bo pošiljal ping vsakih 15 sekund in začnemo poslušati kanal, na katerega smo naročeni. Če prejmemo ping, ga objavimo. Če prejmemo nekakšen vnos, ga objavimo vsem naročnikom tega Fanouta.

Kako deluje Fan-out?

V ruščini se to prevede kot "razdelilec". Imamo en objekt, ki registrira naročnike, ki želijo prejemati nekaj posodobitev. In takoj ko posodobitev prispe do tega objekta, jo razdeli vsem svojim naročnikom. Dovolj preprosto:

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

Kako je implementirano v Go:

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

Obstaja struktura, sinhronizirana je z uporabo Mutexov. Ima polje, ki shranjuje stanje povezave Fanouta z bazo podatkov, torej trenutno posluša in bo prejemal posodobitve, ter seznam vseh razpoložljivih kanalov - zemljevid, katerega ključ je kanal in struktura v obliki vrednosti (v bistvu se ne uporablja na noben način).

Dve metodi - Connected in Disconnected - omogočata, da Fanoutu povemo, da imamo povezavo z bazo, se je pojavila in da je povezava z bazo prekinjena. V drugem primeru morate odklopiti vse odjemalce in jim povedati, da ne morejo več poslušati ničesar in naj se ponovno povežejo, ker se je povezava z njimi prekinila.

Obstaja tudi metoda Subscribe, ki doda kanal med »poslušalce«:

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

Obstaja metoda Unsubscribe, ki odstrani kanal iz poslušalcev, če odjemalec prekine povezavo, kot tudi metoda Publish, ki vam omogoča pošiljanje sporočila vsem naročnikom.

Vprašanje: – Kaj se prenaša po tem kanalu?

GOSPA: – Model, ki se je spremenil, ali ping se prenaša (v bistvu samo številka, celo število).

GOSPA: – Pošljete lahko karkoli, pošljete poljubno strukturo, objavite – preprosto se spremeni v JSON in to je to.

GOSPA: – Prejmemo obvestilo od Postgresa – vsebuje ime tabele in identifikator. Na podlagi imena tabele in identifikatorja dobimo zapis, ki ga potrebujemo, nato pa to strukturo pošljemo v objavo.

Infrastruktura

Kako je to videti z vidika infrastrukture? Imamo 7 strežnikov strojne opreme: eden je v celoti namenjen bazi podatkov, ostalih šest pa poganja virtualne stroje. Obstaja 6 kopij API-ja: vsak virtualni stroj z API-jem deluje na ločenem strežniku strojne opreme - to je zaradi zanesljivosti.

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

Za izboljšanje dostopnosti imamo nameščeni dve sprednji strani s Keepalivedom, tako da lahko ena sprednja stran zamenja drugo, če se kaj zgodi. Tudi – dve kopiji CMS.

Obstaja tudi uvoznik statistike. Obstaja DB Slave, iz katerega se občasno izdelujejo varnostne kopije. Obstaja Pigeon Pusher, aplikacija, ki strankam pošilja potisna obvestila, pa tudi infrastrukturne stvari: Zabbix, Graylog2 in Chef.

Pravzaprav je ta infrastruktura odvečna, saj je 100 tisoč možno postreči z manj strežniki. Vendar je bilo železo - uporabili smo ga (rečeno nam je bilo, da je to mogoče - zakaj ne).

Prednosti Go

Ko smo delali na tej aplikaciji, so se pokazale tako očitne prednosti Go.

  • Kul http knjižnica. Z njim lahko ustvarite kar nekaj iz škatlice.
  • Poleg tega kanali, ki so nam omogočili zelo enostavno implementacijo mehanizma za pošiljanje obvestil strankam.
  • Čudovita stvar Race detektor nam je omogočila, da smo odpravili več kritičnih hroščev (uprizoritvena infrastruktura). Vse, kar deluje na stopnji, se zažene, prevede s ključem Race; in v skladu s tem lahko pogledamo uprizoritveno infrastrukturo, da vidimo, kakšne morebitne težave imamo.
  • Minimalizem in preprostost jezika.

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

Iščemo razvijalce! Če kdo želi, prosim.

vprašanja

Vprašanje iz občinstva (v nadaljevanju – B): – Zdi se mi, da ste spregledali eno pomembno točko glede Fan-outa. Ali prav razumem, da ko stranki pošljete odgovor, blokirate, če stranka ne želi brati?

GOSPA: - Ne, ne blokiramo. Prvič, vse to imamo za nginxom, se pravi, da ni težav s počasnimi odjemalci. Drugič, odjemalec ima kanal z medpomnilnikom - pravzaprav lahko tja damo do sto posodobitev ... Če ne moremo pisati v kanal, ga izbriše. Če vidimo, da je kanal blokiran, bomo preprosto zaprli kanal in to je to - odjemalec se bo znova povezal, če bo prišlo do kakršne koli težave. Zato tu načeloma ni blokade.

V: – Ali ne bi bilo mogoče takoj poslati zapisa v Listen/Notify in ne identifikatorske tabele?

GOSPA: – Listen/Notify ima omejitev 8 tisoč bajtov za predhodno nalaganje, ki ga pošlje. Načeloma bi bilo možno pošiljati, če bi imeli opravka z majhno količino podatkov, vendar se mi zdi, da je ta način [način, kako to počnemo] preprosto bolj zanesljiv. Omejitve so v samem Postgresu.

V: – Ali stranke prejemajo posodobitve o tekmah, ki jih ne zanimajo?

GOSPA: - Na splošno ja. Praviloma potekajo 2-3 tekme vzporedno, pa še to zelo redko. Če stranka nekaj gleda, potem običajno gleda tekmo, ki se dogaja. Nato ima odjemalec lokalno bazo podatkov, v katero se seštejejo vse te posodobitve in tudi brez internetne povezave si lahko odjemalec ogleda vse pretekle tekme, za katere ima posodobitve. V bistvu sinhroniziramo našo bazo podatkov na strežniku z odjemalčevo lokalno bazo podatkov, tako da lahko dela brez povezave.

V: – Zakaj ste naredili svoj ORM?

Alexey (eden od razvijalcev Look+): – Takrat (bilo je leto nazaj) je bilo ORM-jev manj kot zdaj, ko jih je kar veliko. Moja najljubša stvar pri večini ORM-jev je, da jih večina deluje na praznih vmesnikih. To pomeni, da so metode v teh ORM-jih pripravljene prevzeti karkoli: strukturo, kazalec strukture, številko, nekaj popolnoma nepomembnega ...

Naš ORM generira strukture na podlagi podatkovnega modela. sebe. In zato so vse metode konkretne, ne uporabljajo refleksije itd. Sprejemajo strukture in pričakujejo uporabo teh struktur, ki pridejo.

V: – Koliko ljudi je sodelovalo?

GOSPA: – Na začetni stopnji sta sodelovali dve osebi. Začeli smo nekje junija, avgusta pa je bil glavni del pripravljen (prva verzija). Septembra je bila izdaja.

V: – Kjer opisujete SSE, ne uporabljate časovne omejitve. Zakaj?

GOSPA: – Če sem iskren, je SSE še vedno protokol html5: standard SSE je zasnovan za komunikacijo z brskalniki, kolikor razumem. Ima dodatne funkcije, da se lahko brskalniki ponovno povežejo (in tako naprej), vendar jih ne potrebujemo, ker smo imeli odjemalce, ki so lahko implementirali kakršno koli logiko za povezovanje in prejemanje informacij. Nismo naredili SSE, ampak nekaj podobnega SSE. To ni sam protokol.
Ni bilo potrebe. Kolikor razumem, so stranke povezovalni mehanizem implementirale skoraj iz nič. Pravzaprav jim je bilo vseeno.

V: – Katere dodatne pripomočke ste uporabili?

GOSPA: – Za poenotenje sloga smo najbolj aktivno uporabljali govet in golint, pa tudi gofmt. Nič drugega ni bilo uporabljeno.

V: – Kaj ste uporabili za odpravljanje napak?

GOSPA: – Odpravljanje napak je bilo v veliki meri izvedeno s testi. Nismo uporabili nobenega razhroščevalnika ali GOP-ja.

V: – Ali lahko vrnete diapozitiv, kjer je implementirana funkcija objave? Vas enočrkovna imena spremenljivk zmedejo?

GOSPA: - Ne. Imajo dokaj "ozek" obseg vidnosti. Ne uporabljajo se nikjer drugje razen pri nas (razen za notranjost tega razreda) in je zelo kompakten - traja le 7 vrstic.

V: – Nekako še vedno ni intuitivno ...

GOSPA: - Ne, ne, to je prava koda! Ne gre za stil. To je tako uporaben, zelo majhen razred - samo 3 polja znotraj razreda ...

Mihail Salosin. Srečanje v Golangu. Uporaba Go v ozadju aplikacije Look+

GOSPA: – Na splošno se vsi podatki, ki so sinhronizirani z odjemalci (sezonske tekme, igralci), ne spremenijo. Grobo povedano, če naredimo drug šport, v katerem moramo spremeniti tekmo, bomo preprosto vse upoštevali v novi različici odjemalca, stare različice odjemalca pa bodo prepovedane.

V: – Ali obstajajo paketi za upravljanje odvisnosti tretjih oseb?

GOSPA: – Uporabili smo go dep.

V: – V temi poročila je bilo nekaj o videu, v poročilu pa ni bilo ničesar o videu.

GOSPA: – Ne, v temi nimam ničesar o videu. Imenuje se "Look+" - to je ime aplikacije.

V: – Rekli ste, da se pretaka strankam?..

GOSPA: – Nismo sodelovali pri pretočnem videu. To je v celoti naredil Megafon. Da, nisem rekel, da je aplikacija MegaFon.

GOSPA: – Go – za pošiljanje vseh podatkov – o rezultatu, dogodkih tekem, statistiki... Go je celotno zaledje aplikacije. Stranka mora od nekje vedeti, katero povezavo uporabiti za igralca, da lahko uporabnik gleda tekmo. Imamo pripravljene povezave do videoposnetkov in tokov.

Nekaj ​​oglasov 🙂

Hvala, ker ste ostali z nami. So vam všeč naši članki? Želite videti več zanimivih vsebin? Podprite nas tako, da oddate naročilo ali priporočite prijateljem, oblak VPS za razvijalce od 4.99 $, edinstven analog začetnih strežnikov, ki smo ga izumili za vas: Vsa resnica o VPS (KVM) E5-2697 v3 (6 jeder) 10 GB DDR4 480 GB SSD 1 Gbps od 19 USD ali kako deliti strežnik? (na voljo z RAID1 in RAID10, do 24 jeder in do 40 GB DDR4).

Dell R730xd dvakrat cenejši v podatkovnem centru Equinix Tier IV v Amsterdamu? Samo tukaj 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6 GHz 14C 64 GB DDR4 4 x 960 GB SSD 1 Gbps 100 TV od 199 $ na Nizozemskem! Dell R420 - 2x E5-2430 2.2 Ghz 6C 128 GB DDR3 2x960 GB SSD 1 Gbps 100 TB - od 99 $! Preberite o Kako zgraditi infrastrukturo Corp. razreda z uporabo strežnikov Dell R730xd E5-2650 v4 v vrednosti 9000 evrov za drobiž?

Vir: www.habr.com

Dodaj komentar