Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

Mihhail Salosin (edasi – MS): – Tere kĂ”igile! Minu nimi on Mihhail. Olen MC2 Software'is tagaplaanide arendaja ja rÀÀgin teile Go kasutamisest mobiilirakenduse «Sotri+» tagaplaanis.

Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

Kas keegi kohalolejatest armastab hoki?

Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

Siis on see rakendus teie jaoks. See on mĂ”eldud Androidile ja iOS-ile, vĂ”imaldades vaadata erinevate spordisĂŒndmuste otse- ja jĂ€relvaatamise ĂŒlekandeid. Rakenduses on ka erinev statistika, tekstilised ĂŒlekanded, koosseisud turniiride ja konverentside jaoks ning muu teave, mis on fĂ€nnide jaoks kasulik.

Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

Rakenduses on ka funktsioon, nagu videomomendid, st saate vaadata mĂ€ngude teravaid hetki (vĂ€ravad, kaklused, karistuslöögid jne). Kui te ei soovi vaadata kogu ĂŒlekanne, siis saate vaadata ainult kĂ”ige huvitavamat.

Mida kasutati arenduses?

Peamine osa oli kirjutatud Go keeles. API, millega suhtlesid mobiilklientide programmid, oli samuti kirjutatud Go keeles. Push-teadete saatmiseks mobiilidesse oli samuti kasutatud Go keelt. Lisaks pidime kirjutama oma ORM-i, millest rÀÀgime ehk kunagi tulevikus. Go keeles on kirjutatud ka mĂ”ned vĂ€ikesed teenused: piltide suuruse muutmine ja ĂŒleslaadimine toimetajate poole


Andmebaasina kasutasime PostgreSQL-i. Toimetajate liides oli kirjutatud Ruby on Railsis kasutades ActiveAdmini gemi. Statistika, mille importimiseks kasutasime Ruby keelt, tuli statistikapakkujalt.

API sĂŒsteemitestide jaoks kasutasime Pythonis unittesti. API maksete pĂ€ringute ĂŒlevaate kontrollimiseks kasutatakse Memcached'i, konfiguratsiooni haldamiseks Chef'i ning sisemiste statistiliste andmete kogumiseks ja jĂ€lgimiseks Zabbix'i. Logide kogumiseks kasutame Graylog2 ja API dokumentatsiooniks klientidele on Slate.

Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

Protokolli valik

Esimene probleem, millega silmitsi seisisime: pidime valima protokolli, mille kaudu toimub suhtlemine taustsĂŒsteemi ja mobiilsete klientide vahel, tuginedes jĂ€rgmistele punktidele


  • Peamine nĂ”ue: kliendiandmed peavad vĂ€rskenduma reaalajas. See tĂ€hendab, et kĂ”ik, kes hetkel vaatavad ĂŒlekanne, peaksid saama vĂ€rskendusi praktiliselt koheselt.
  • Lihtsustamiseks oletame, et andmed, mis sĂŒnkroniseeritakse klientidega, ei eemaldata, vaid peidetakse spetsiaalsete lipukestega.
  • MĂ”ned haruldased pĂ€ringud (nt statistika, meeskondade koosseis, meeskondade statistika) saadakse tavaliste GET-pĂ€ringutega.
  • Lisaks pidi sĂŒsteem taluma rahulikult 100 000 kasutajat samaaegselt.

SeetÔttu oli meil kaks protokollivalikut:

  1. Websocketid. Kuid me ei vajanud kanalit kliendilt serverile. Meile oli vajalik ainult vĂ€rskenduste saatmine serverist kliendile, mistĂ”ttu oli veebisoket ĂŒleliigne variant.
  2. Server-Sent Events (SSE) sobis ideaalselt! See on piisavalt lihtne ja rahuldab pÔhimÔtteliselt kÔiki meie vajadusi.

Server-Sent Events

MĂ”ned sĂ”nad selle sĂŒsteemi toimimise kohta...

See töötab http-ĂŒhenduse peal. Klient saadab pĂ€ringu, server vastab Content-Type: text/event-stream ja ei sulge ĂŒhendust, vaid jĂ€tkab andmete kirjutamist sellesse ĂŒhendusse.

Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

Andmed saab saata kliendi heakskiidetud vormingus. Meie puhul saatsime me seda selliselt: event vÀljale saadeti muudetud struktuuri nimi (inimene, mÀngija), ja data vÀljale - JSON uute, muudetud mÀngija vÀli-dega.

NĂŒĂŒd rÀÀgime, kuidas ise suhtlus toimib.

  • KĂ”igepealt mÀÀrab klient, millal viimane kord sĂŒndis sĂŒnkroniseerimine teenusega: ta vaatab oma lokaalsesse andmebaasi ja mÀÀrab viimase muudatuse kuupĂ€eva, mis tal on salvestatud.
  • Ta saadab pĂ€ringu koos selle kuupĂ€evaga.
  • Vastuseks saadame me talle kĂ”ik vĂ€rskendused, mis on toimunud alates sellest kuupĂ€evast.
  • PĂ€rast seda loob ta ĂŒhenduse live-kanaliga ja ei sulge seda, kuni need vĂ€rskendused on vajalikud:

Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

Me saadame talle muudatuste loendi: kui keegi lĂ”i vĂ€rava - muudame mĂ€ngu skoori, kui keegi sai vigastada - saadetakse see samuti reaalajas. Seega saavad kliendid mĂ€ngu sĂŒndmuste voos koheselt ajakohased andmed. Aeg-ajalt, et klient saaks aru, et server ei ole kokku kukkunud, et temaga ei ole midagi juhtunud, saadame me iga 15 sekundi jĂ€rel timestamp'i - et ta teaks, et kĂ”ik on korras ja ta ei pea uuesti ĂŒhendust looma.

Kuidas toimub live-ĂŒhenduse haldamine?

  • Esiteks loome kanali, kuhu saadetakse uuendusi koos puhvriga.
  • PĂ€rast seda registreerime selle kanali uuenduste saamiseks.
  • Seame Ă”ige pealkirja, et klient teaks, et kĂ”ik on korras.
  • Saadame esimese ping'i. Lihtsalt salvestame praeguse ĂŒhenduse ajamĂ€rgi.
  • SeejĂ€rel loeme silmuses kanalist kuni uuenduste kanal on suletud. Kanalile saadetakse perioodiliselt kas praegune ajamĂ€rk vĂ”i muudatused, mille me juba salvestame avatud ĂŒhendustes.

Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

Esimene probleem, millega silmitsi seisisime, oli jĂ€rgmine: igale avatud kliendiĂŒhendusele loodi taimer, mis tiksus iga 15 sekundi tagant – tĂ€hendab, et kui meil oli avatud 6000 ĂŒhendust ĂŒhe masinaga (ĂŒhe API-serveriga), siis loodi 6000 taimerit. See tĂ”i kaasa selle, et masin ei suutnud vajalikku koormust taluda. Probleem ei olnud meie jaoks nii ilmne, kuid me saime veidi abi ja lahendasime selle.

Sellest ajast saadik tuleb meie ping samast kanalist, kust tuleb ka uuendus.

Seega on meil ainult ĂŒks taimer, mis tiksub iga 15 sekundi tagant.

Siin on mĂ”ned abifunktsioonid – pealkirjade saatmine, pingi ja struktuuri saatmine. See tĂ€hendab, et edastatakse tabeli nimi (isiku, mĂ€ngu, hooaja) ja teave selle kirje kohta:

Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

Uuenduste saatmise mehhanism

NĂŒĂŒd rÀÀgime veidi sellest, kust muutused tulevad. Meil on mĂ”ned inimesed, toimetajad, kes jĂ€lgivad reaalajas edastust. Nad loovad kĂ”ik sĂŒndmused: kedagi eemaldatakse, keegi saab vigastada, toimub vahetus...

CMS-i kaudu jĂ”uavad andmed andmebaasi. PĂ€rast seda teavitab andmebaas mehhanismi Listen/Notify abil API-servereid. API-serverid jagavad selle teabe klientidele. Seega on meil pĂ”himĂ”tteliselt andmebaasiga ĂŒhendatud vaid mĂ”ned serverid ning andmebaasile ei ole erilist koormust, kuna klient ei suhtle andmebaasiga otseselt:

Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

PostgreSQL: Listen/Notify

Listen/Notify mehhanism „Postgreses“ vĂ”imaldab teavitada sĂŒndmuste tellijaid, et mĂ”ni sĂŒndmus on muutunud – andmebaasis on loodud mĂ”ni uus kirje. Selleks kirjutasime lihtsa trigeri ja funktsiooni:

Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

Insert vÔi kirje muutmise korral kutsume andmekanalis data_updates vÀlja notify funktsiooni, edastades sinna tabeli nime ja muudetud vÔi sisestatud kirje ID.

KĂ”ikidele tabelitele, mis peavad olema kliendiga sĂŒnkroniseeritud, defineerime kĂ€ivitaja, mis pĂ€rast kirje muutmist/uendamist kutsub vĂ€lja slaidil allpool nĂ€idatud funktsiooni.
Kuidas API nendest muudatustest teada saab?

Loodud on Fanout mehhanism – see saadab sĂ”numeid klientidele. See kogub kĂ”ik kliendi kanalid ja edastab neile saadud uuendused:

Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

Siin on standardne teek pq, mis ĂŒhendub andmebaasiga ja ĂŒtleb, et soovib kuulata kanalit (data_updates), kontrollides, et ĂŒhendus on avatud ja kĂ”ik on korras. JĂ€tan veateate kontrollimise vĂ€lja, et ruumi kokku hoida (kontrollimata jĂ€tmine vĂ”ib olla ohtlik).

SeejĂ€rel mÀÀrame asĂŒnkroonselt Ticker'i, mis saadab ping'i iga 15 sekundi tagant, ja hakkame kuulama kanali, millele oleme tellinud. Kui saame ping'i, avaldame selle. Kui saame mĂ”ne kirje, avaldame selle kĂ”ikidele selle Fanout'i tellijatele.

Kuidas Fan-out töötab?

Eesti keeles tĂ”lgitakse see kui "haruĂŒhendus". Meil on ĂŒks objekt, mis registreerib tellijad, kes soovivad saada mingit teavet. Ja kui sellele objektile tuleb uuendus, jagab ta selle uuenduse kĂ”ikidele tellijatele, kellel see on. Suhteliselt lihtne:

Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

Kuidas seda Go's rakendatakse:

Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

On struktuur, mis sĂŒnkroniseeritakse Mutex'ide abil. Sellel on vĂ€li, mis salvestab Fanout'i ĂŒhenduse oleku andmebaasiga, st hetkel kuulab see ja saab uuendusi, samuti on olemas kĂ”igi kanalite nimekiri – map, mille vĂ”tmed on kanal ja struktuur vÀÀrtustena (seda ei kasutata tegelikult millegiks).

Kahe meetodiga – Connected ja Disconnected – saab Fanout’ile öelda, et meil on ĂŒhendus andmebaasiga, see on tekkinud, ja et andmebaasiĂŒhendus on katkestatud. Teisel juhul tuleb kĂ”ik kliendid lahti ĂŒhendada ja neile teatada, et nad ei saa enam midagi kuulata ja paluda neil uuesti ĂŒhendada, kuna nendega side on katkenud.

Samuti on olemas meetod Subscribe, mis lisab kanali "kuulajate" hulka:

Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

On olemas Unsubscribe meetod, mis eemaldas kanali kuulajatest, kui klient on vĂ€lja lĂŒlitatud, samuti Publish meetod, mis vĂ”imaldab sĂ”numit saata kĂ”igile tellijatele.

KĂŒsimus: – Mida selle kanali kaudu edastatakse?

M: – Edastatakse mudel, mis on muutunud, vĂ”i ping (pĂ”himĂ”tteliselt lihtsalt number, integer).

M: – VĂ”ib edastada ĂŒkskĂ”ik mida, igasuguseid struktuure – need lihtsalt muudetakse JSON-ks ja kĂ”ik.

M: – Saame teate Postgres'ist – see sisaldab tabeli nime ja identifikaatorit. Tabeli nime pĂ”hjal saame ja identifikaatori pĂ”hjal saame vajaliku kirje, ning selle struktuuri saadame avaldamiseks.

Infrastruktuur

Kuidas see infrastruktuuri vaatepunktist vĂ€lja nĂ€eb? Meil on 7 fĂŒĂŒsilist serverit: ĂŒks neist on tĂ€ielikult pĂŒhendatud andmebaasile, ĂŒlejÀÀnud kuuel töötavad virtuaalmasinad. Kuuest API koopiatest: iga virtuaalmasin API-ga töötab eraldi fĂŒĂŒsilisel serveril – see on usaldusvÀÀrsuse jaoks.

Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

Meil on kaks frontend'i, millel on installitud Keepalived, et parandada kĂ€ttesaadavust, et vajadusel saaks ĂŒks frontend asendada teise. Veel – kaks CMS koopiat.

Samuti on olemas statistika importija. On DB Slave, millest tehakse perioodiliselt varukoopiaid. On Pigeon Pusher – rakendus, mis saadab klientidele push-teateid, samuti infrastruktuursed asjad: Zabbix, Graylog2 ja Chef.

Tegelikult on see infrastruktuur ĂŒleliigne, sest 100 000 klienti saab teenindada ka vĂ€iksema serverite arvuga. Kuid kuna riistvara oli olemas, kasutasime seda (meile öeldi, et see on vĂ”imalik – miks mitte).

Go eelised

PÀrast seda, kui me selle rakenduse kallal töötasime, ilmnesid Go selged eelised.

  • SuurepĂ€rane http-raamatukogu. Selle abil saab juba "karbist vĂ€lja" pĂ€ris palju luua.
  • Lisaks vĂ”imaldavad kanalid meil vĂ€ga lihtsalt rakendada teatiste saatmise mehhanismi klientidele.
  • Imeline asi Race detector vĂ”imaldas meil kĂ”rvaldada mitu kriitilist viga (staging-infrastruktuur). KĂ”ik, mis töötab staging'is – on kĂ€ivitatud, kompileeritud Race-vĂ”tmega; ja seega saame staging-infrastruktuuris vaadata, millised potentsiaalsed probleemid meil on.
  • Keeles on minimalism ja lihtsus.

Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

Otsime arendajaid! Kui keegi on huvitatud – palun.

KĂŒsimused

KĂŒsimus publikust (edaspidi – K): – Olen arvamusel, et jĂ€tsite ĂŒhe olulise momendi Fan-out'i osas kĂ€sitlemata. Kas ma saan Ă”igesti aru, et kui saadate kliendile vastuse, siis te blokeerite, kui klient ei soovi lugeda?

M: – Ei, me ei blokeeri. Esiteks on meie teenused kĂ”ik nginx'i taga, seega ei esine probleeme aeglaste klientidega. Teiseks, kliendil on kanalis puhversĂŒsteem – tegelikult saame sinna saata kuni sada uuendust... Kui me ei saa kanalisse kirjutada, siis ta kustutab selle. Kui mĂ€rkame, et kanal on blokeeritud, siis me lihtsalt sulgeme kanali ja kĂ”ik – klient reconnect'ib, kui tekkima peaks mingi probleem. Seega ei esine siin pĂ”himĂ”tteliselt blokeeringut.

K: – Kas ei oleks olnud vĂ”imalik kohe saata Listen/Notify kaudu kirje, mitte tabeli identifikaator?

M: – Listen/Notify'il on 8000 baitine piirang eelkoormusele, mille ta saadab. Teoreetiliselt oleks saanud saata, kui meil oleks vĂ€he andmeid, kuid mulle tundub, et see [nagu meie teeme] on lihtsalt usaldusvÀÀrsem. Piirangud on Postgreses endas.

K: – Kas kliendid saavad uuendusi mĂ€ngudest, mis neid ei huvita?

M: – Üldiselt jah. TĂŒĂŒpiliselt toimub seal 2-3 matĆĄi samal ajal, ja see on isegi harva. Kui klient vaatab midagi, siis tavaliselt vaatab ta just seda matĆĄi, mis kĂ€ib. SeejĂ€rel on kliendil kohalik andmebaas, kuhu kĂ”ik need uuendused kogunevad, ja isegi ilma internetiĂŒhenduseta saab klient vaadata kĂ”iki toimunud matĆĄe, mille kohta tal on uuendusi. PĂ”himĂ”tteliselt sĂŒnkroniseerime oma andmebaasi serveris kliendi kohaliku andmebaasiga, et ta saaks töötada ka offline.

K: – Miks te tegite oma ORM-i?

Aleksei (ĂŒks „Smotri+” arendajatest): – Sel hetkel (see oli aasta tagasi) oli ORM-e vĂ€hem kui praegu, kui neid on juba ĂŒsna palju. Enamik olemasolevaid ORM-e mulle ei meeldi, kuna enamik neist töötab tĂŒhjade liideste peal. See tĂ€hendab, et nende ORM-ide meetodid on valmis vastu vĂ”tma mida iganes: struktuuri, struktuuri viidatud, arvu, midagi tĂ€iesti asjatu...

Meie ORM genereerib struktuure andmemudeli alusel. Iseseisvalt. Ja seetÔttu on kÔik meetodid konkreetsed, ei kasuta refleksiooni jne. Nad vÔtavad vastu struktuure ja ootavad, et kasutada neid struktuure, mis sisenevad.

K: – Kui palju inimesi osales?

M: – Algfaasis osales kaks inimest. Kuskil juunis me alustasime, augustiks oli enamus valmis (esimene versioon). Septembris toimus vĂ€ljaanne.

K: – Seal, kus kirjeldate SSE-d, te ei kasuta timeout'i. Miks nii?

M: – Ausalt öeldes on SSE ikkagi HTML5 protokoll: SSE standard on mĂ”eldud suhtlemiseks brauseritega, kui ma Ă”igesti aru saan. Sellel on lisafunktsioonid, et brauserid saaksid uuesti ĂŒhendada (ja muud), kuid neid pole meil vaja, kuna meie kliendid suudavad rakendada mis tahes ĂŒhenduse ja teabe saamise loogikat. Me olime teinud pigem mitte SSE, vaid midagi SSE-taolist. See ei ole protokoll ise.
Pole olnud vajadust. Kui ma Ă”igesti aru saan, siis kliendid rakendasid ĂŒhenduse mehhanismi praktiliselt nullist. Nad ei hoolinud sellest ĂŒldse.

K: – Milliseid lisatööriistu te kasutasite?

M: – KĂ”ige aktiivsemalt kasutasime govet ja golint, et stiil oleks ĂŒhtlane, samuti gofmt. Muid ei kasutanud.

K: – Kuidas te kĂ€rpimist tegite?

M: – KĂ€rpimist tehti pĂ”himĂ”tteliselt testide abil. Me ei kasutanud mingit debugeerijat, GOP-i.

K: – Kas sa saad tagasi tuua slaidi, kus on rakendatud Publish funktsioon? Kas ĂŒhekohalised muutuja nimetused ei hĂ€iri sind?

M: – Ei. Neil on piisavalt „kitsas” ulatus. Nad ei kasuta ennast kusagil mujal, vĂ€lja arvatud siin (vĂ€lja arvatud selle klassi sees), ja see on vĂ€ga kompaktne – hĂ”lmab vaid 7 rida.

K: – Kuidaski tundub see ikkagi mitte intuitiivne


M: – Ei-Ă€rk, see on tĂ”eline kood! KĂŒsimus ei ole stiilis. See on lihtsalt nii utilitaarne, tĂ€iesti vĂ€ike klass – ainult 3 vĂ€lja klassi sees


Mihhail Salosin. Golang Meetup. Go kasutamine rakenduse "Smotri+" tagaplaanil.

M: – Üldiselt ei muutu kĂ”ik need andmed, mis sĂŒnkroonitakse klientidega (hooaegade mĂ€ngud, mĂ€ngijad). Ütleme niimoodi, et kui me teeme mĂ”ne muu spordiala, kus tuleb mĂ€ngu muuta, siis arvestame sellega lihtsalt uues kliendi versioonis, ja vanad versioonid blokeeritakse.

K: – Kas on olemas mingeid kolmanda osapoole pakette sĂ”ltuvuste haldamiseks?

M: – Me kasutasime go dep.

K: – Ettekande teemal oli midagi videotest, aga ettekandes video kohta ei ole.

M: – Ei, minul ei ole teemas midagi video kohta. See nimi on „Sootri+” – nii nimetatakse seda rakendust.

K: – Kas sa rÀÀkisid, et seda edastatakse klientidele?..

M: – Me ei ole tegelenud voogedastuse videoga. Selle tegi tĂ€ielikult „MegaFon“. Jah, ma ei maininud, et see on MegaFoni rakendus.

M: – Go – kĂ”igi andmete edastamiseks – arve, mĂ€nguĂŒrituste, statistika
 Go on tĂ€ielik backend rakendusele. Klient peab kusagilt teadma, millist linki kasutada mĂ€ngija jaoks, et kasutaja saaks mĂ€ngu vaadata. Meil on videolinkide ja voogedastuste lingid, mis on ette valmistatud.

Vaata videot

Veidi reklaami 🙂

AitĂ€h, et olete meiega. Kas teile meeldivad meie artiklid? Kas soovite nĂ€ha rohkem huvitavaid materjale? Toetage meid, tehes tellimuse vĂ”i soovitades meid tuttavatele. pilve VPS arendajatele alates $4,99, ainulaadne sisenemise taseme serverite analoog, mille oleme teie jaoks vĂ€lja mĂ”elnud: Kogu tĂ”de VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps alates $19 vĂ”i kuidas Ă”ieti serverit jagada? (saadaval on RAID1 ja RAID10 variandid, kuni 24 sĂŒdamikku ja kuni 40GB DDR4).

Kas Dell R730xd on kaks korda odavam Equinixi Tier IV andmete keskuses Amsterdamis? Ainult meie juures 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TB alates $199 Hollandi turul! Dell R420 — 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — alates $99! Lugege, kuidas Luua ettevĂ”tte tasemel infrastruktuur Dell R730xd E5-2650 v4 serveritega, mille hind on 9000 eurot, madala hinnaga?

Allikas: habr.com

Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster