Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

Mihhail Salosin (edasi – MS): – Tere kĂ”igile! Minu nimi on Mihhail. Töödan tagaroboti arendajana ettevĂ”ttes MC2 Software, ja rÀÀgin kasutusest Go mobiilirakenduse «Sotri+» tagaroboti pool.

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

Kas keegi kohalolejatest armastab hokit?

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

Siis on see rakendus just sinule. See on mĂ”eldud Androidile ja iOS-ile ning vĂ”imaldab vaadata erinevate spordisĂŒndmuste ĂŒlekandeid reaalajas ja jĂ€relvaatamiseks. Rakenduses on ka erinev statistika, tekstilised ĂŒlekanded, tabelid konverentsidest, turniiridest ja muu teave, mis on kasulik fĂ€nnidele.

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

Rakenduses on ka selline asi nagu videomomendid, st saab vaadata kohtumise teravaid hetki (vĂ€ravaid, kaklusi, bullete jne). Kui sa ei soovi vaadata kogu ĂŒlekannet, saad vaadata ainult kĂ”ige huvitavamat.

Mida me arenduses kasutasime?

Peamine osa kirjutati Go keeles. See API, millega mobiilsed kliendid suhtlesid, kirjutati samuti Go keeles. Samuti oli Go keeles kirjutatud teenus push-teadete saatmiseks mobiilidele. Me pidime ka kirjutama oma ORM-i, millest me vĂ”ib-olla kunagi rÀÀgime. Ja Go keeles on kirjutatud mĂ”ned vĂ€ikesed teenused: piltide suuruse muutmine ja ĂŒleslaadimine toimetajate poole


Andmebaasina kasutasime PostgreSQL-i. Toimetajate liides oli kirjutatud Ruby on Railsis ActiveAdmin gem'i abil. Ruby keeles on kirjutatud ka statistika import, mis tuleb statistika tarnijalt.

API sĂŒsteemitestide jaoks kasutasime Pythonis unittesti. Memcached'i kasutatakse API-de makse jupitamiseks, Chef'i – konfiguratsiooni haldamiseks, Zabbix'i – sĂŒsteemi sise statistikate kogumiseks ja jĂ€lgimiseks. Graylog2 – logide kogumiseks, Slate – dokumentatsioon API klientidele.

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

Protokolli valik

Esiteks probleem, millega me silmitsi seisis: pidime valima protokolli, millega tagarobot suheldes mobiilsete klientidega pÔhinedes jÀrgmistel punktidel...

  • Suurim nĂ”ue: andmed klientides peavad uuenduma reaalajas. St kĂ”ik, kes hetkel vaatavad ĂŒlekannet, peavad saama uuendusi praktiliselt koheselt.
  • Lihtsustamiseks nĂ”ustusime, et andmed, mis sĂŒnkroniseeritakse klientidega, ei kustutata, vaid peidetakse spetsiaalsete lipukestega.
  • Iga haruldased pĂ€ringud (nagu statistika, meeskondade koosseisud, meeskondade statistika) saadakse tavapĂ€raste GET-pĂ€ringutega.
  • Lisaks pidi sĂŒsteem rahulikult taluma 100 000 samaaegset kasutajat.

Sellega seoses oli meil kaks protokollivÔimalust:

  1. Websocketid. Kuid me ei vajanud klientsideme kanaleid. Me vajame ainult andmete saatmist serverilt kliendile, seega on veebisokett liialdus.
  2. Server-Sent Events (SSE) sobis suurepÀraselt! See on piisavalt lihtne ja rahuldab pÔhimÔtteliselt kÔike, mida me vajame.

Server-Sent Events

MÔned sÔnad selle asja toimimise kohta


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

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

Andmeid saab saata kliendiga kokkulepitud formaadis. Meie puhul saatsime seda kujul: event vĂ€ljas oli muudetud struktuuri nimi (inimene, mĂ€ngija), ja data vĂ€ljas – JSON koos uute, muudetud mĂ€ngija vĂ€ljadega.

NĂŒĂŒd rÀÀgime, kuidas toimub interaktsioon.

  • Esmalt mÀÀrab klient, millal viimati toimus sĂŒnkroniseerimine teenusega: ta vaatab oma kohalikku andmebaasi ja mÀÀrab viimase muudatuse kuupĂ€eva.
  • Ta saadab pĂ€ringu koos selle kuupĂ€evaga.
  • Vastuseks saadame talle kĂ”ik uuendused, mis on toimunud pĂ€rast seda kuupĂ€eva.
  • PĂ€rast seda loob ta ĂŒhenduse live-kanaliga ja ei sulge seda enne, kui tal on neid uuendusi vaja:

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

Me saadame talle muudatuste loendi: kui keegi lĂ”i vĂ€rava – muudame mĂ€ngu tulemust, kui keegi sai vigastada – saadame ka seda reaalajas. Seega saavad kliendid mĂ€ngu sĂŒndmuste voo kaudu kohe vĂ€rskeid andmeid. Aeg-ajalt, et klient mĂ”istaks, et server ei ole surnud ja temaga ei ole midagi juhtunud, saadame iga 15 sekundi tagant timestampi – et ta teaks, et kĂ”ik on korras ja uuesti ĂŒhendust pole vaja luua.

Kuidas teenindatakse live-ĂŒhendust?

  • Esiteks loome kanali, kuhu uudised tulevad koos mahutiga.
  • PĂ€rast seda registreerime selle kanali uuenduste vastuvĂ”tmiseks.
  • Seame Ă”ige pĂ€ise, et klient teaks, et kĂ”ik on korras.
  • Saadame esimese pingi. Lihtsalt salvestame ĂŒhenduse hetketimestampi.
  • PĂ€rast seda loeme tsĂŒklis kanalist seni, kuni vĂ€rskenduste kanal on suletud. Kanalisse tuleb perioodiliselt kas praegune ajatemperatuur vĂ”i muudatused, mille me juba salvestame avatud ĂŒhendustesse.

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

Esimene probleem, millega me silmitsi seisime, oli see, et iga kliendiga avatud ĂŒhenduse jaoks lĂ”ime taimeri, mis tiksus iga 15 sekundi tagant – seega, kui meil oli avatud 6000 ĂŒhendust ĂŒhe masina (ĂŒhe API-serveri) kaudu, loodi 6000 taimerit. See viis selleni, et masin ei suutnud vajalikku koormust taluda. Probleem ei olnud meie jaoks nii ilmne, kuid me saime veidi abi ja lahendasime selle.

NĂŒĂŒd tuleb meil ping samast kanalist, kust tuleb ka uuendus.

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

Siin on mitu abifunktsiooni – pealkirja, pingi ja struktuuri saatmine. See tĂ€hendab, et edastatakse tabeli nimi (person, match, season) ja selle kirje teave:

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

Uuenduste saatmise mehhanism

NĂŒĂŒd natuke sellest, kust muudatused tulevad. Meil on mitu inimest, toimetajaid, kes jĂ€lgivad reaalajas ĂŒlekandeid. Nad loovad kĂ”ik sĂŒndmused: kedagi eemaldati, keegi sai vigastada, mingi vahetus


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

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

PostgreSQL: Listen/Notify

Listen/Notify mehhanism PostgreSQL-is vĂ”imaldab teavitada sĂŒndmuste tellijaid, et mĂ”ni sĂŒndmus on muutunud – andmebaasis on loodud mĂ”ni uus rida. Selleks kirjutasime lihtsa trigri ja funktsiooni:

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

Insertimise vÔi kirje muutmise korral kutsume kanalis data_updates esile funktsiooni notify, edastades sinna tabeli nime ja muudetud vÔi sisestatud kirje identifitseerija.

KĂ”ikidele tabelitele, mis peavad olema kliendiga sĂŒnkroniseeritud, mÀÀrame trigri, mis pĂ€rast kirje muutmist/vĂ€rskendamist kutsub vĂ€lja alloleval slaidil mÀÀratud funktsiooni.
Kuidas API nende muudatuste tellimiseks registreerub?

Loodi Fanout mehhanismi – see saadab teadet klientidele. See kogub kĂ”ikide klientide kanalid ja saadab neile vĂ€rskendused, mida ta nendelt kanalitelt sai:

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

Siin on standardne biblioteek pq, mis ĂŒhendub andmebaasiga ja ĂŒtleb, et soovib kuulata kanalit (data_updates), kontrollib, et ĂŒhendus on avatud ja kĂ”ik on korras. JĂ€tan vigade kontrollimise vĂ€lja, et ruumi sÀÀsta (veadeta jĂ€tmine vĂ”ib olla riskantne).

KĂŒsimus, kuidas me asĂŒnkroonselt mÀÀrame Tickeri, mis saadab ping’i iga 15 sekundi tagant, ja hakkame kuulama kanalit, millele me oleme tellinud. Kui me saame ping’i, avaldame selle ping’i. Kui me saame mingisuguse kirje, avaldame selle kirje kĂ”igile selle Fanout’i tellijatele.

Kuidas Fan-out töötab?

Eestis tĂ”lgitakse seda kui "haru". Meil on ĂŒks objekt, mis registreerib tellijad, kes soovivad saada mingeid vĂ€rskendusi. Ja niipea, kui see objekt saab vĂ€rskenduse, jagab ta selle vĂ€rskenduse kĂ”igile oma olemasolevatele tellijatele. Lihtne:

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

Kuidas see Go-s on rakendatud:

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

Olemas on struktuur, mis sĂŒnkroniseerub Mutexitega. Sellel on vĂ€li, mis hoiab Fanout’i ĂŒhenduse staatust andmebaasi, st hetkel kuuleb ta ja saab vĂ€rskendusi, samuti kĂ”igi olemasolevate kanalite loend – map, mille vĂ”tmed on kanalid ja struct vÀÀrtustena (tĂ”epoolest ei kasutata seda kuidagi).

Kaks meetodit – Connected ja Disconnected – vĂ”imaldavad Fanout’ile öelda, et meil on ĂŒhendus andmebaasiga, see on olemas, ja et ĂŒhendus andmebaasiga on katkestatud. Teisel juhul tuleb kĂ”iki kliente vĂ€lja lĂŒlitada ja teavitada neid, et nad ei saa enam midagi kuulata ja et nad peaksid uuesti ĂŒhenduma, kuna ĂŒhendus nendega on katkenud.

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

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

On olemas meetod Unsubscribe, mis eemaldab kanali kuulajate seast, kui klient on vĂ€lja lĂŒlitunud, ning meetod Publish, mis vĂ”imaldab saata teadet kĂ”igile tellijatele.

KĂŒsimus: – Mis sellel kanalil edastatakse?

MS: – Edastatakse mudel, mis on muutunud vĂ”i ping (tĂ”epoolest lihtsalt number, tĂ€isarv).

MS: – VĂ”id edastada muud, ĂŒkskĂ”ik millist struktuuri, see avaldatakse – see muudetakse lihtsalt JSON-iks ja kĂ”ik.

MS: – Me saame teate „Postgres'ilt” – see sisaldab tabeli nime ja identifikaatorit. Tabeli nime jĂ€rgi saame identifikaatori ja saame vajalikud kirjed, mida saadame seejĂ€rel avaldamiseks.

Infrastruktuur

Kuidas see infrastruktuuri vaatenurgast vĂ€lja nĂ€eb? Meil on 7 fĂŒĂŒsilist serverit: ĂŒks neist on tĂ€ielikult pĂŒhendatud andmebaasile, ĂŒlejÀÀnud kuuel jooksevad virtuaalmasinad. Meil on 6 API koopiat: iga virtuaalmasin, kus API töötab, asub eraldi fĂŒĂŒsilisel serveril – see on usaldusvÀÀrsuse tagamiseks.

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

Meil on kaks frontend'i, millel on paigaldatud Keepalived, et parandada kĂ€ttesaadavust, nii et hĂ€daolukordades suudaks ĂŒks frontend asendada teise. Samuti on kaks CMS koopia.

Samuti on olemas statistika impordija. On DB Slave, millelt tehakse regulaarselt varukoopiaid. On Pigeon Pusher – see rakendus saadab klientidele teateid, koos infrastruktuuri elementidega: Zabbix, Graylog2 ja Chef.

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

Go eelised

PÀrast selle rakendusega töötamist ilmusid esile jÀrgmised ilmne Go eelised.

  • SuurepĂ€rane http-raamatukogu. Selle abil on vĂ”imalik palju luua juba „karbist vĂ€lja”.
  • Ja kanalid, mis vĂ”imaldasid meil vĂ€ga lihtsalt rakendada klientidele teadete saatmise mehhanismi.
  • Imeline asi, Race detector, aitas meil kĂ”rvaldada mitmeid kriitilisi vigu (staging-infrastruktuur). KĂ”ik, mis töötab staging'is – on kĂ€ivitatud, kompileeritud Race vĂ”tmega; seega saame staging-infrastruktuuris vaadata, millised potentsiaalsed probleemid meil on.
  • Keele minimalism ja lihtsus.

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

Otsime arendajaid! Kui keegi on huvitatud – palun.

KĂŒsimused

KĂŒsimus publikult (edaspidi – K): – Tundub, et te jĂ€tsite ĂŒhe olulise hetke Fan-out osas tĂ€helepanuta. Kas ma Ă”igesti mĂ”istan, et kui saadate kliendile vastuse, jÀÀte kinni, kui klient ei soovi lugeda?

MS: – Ei, me ei blokeeri. Esiteks on kĂ”ik meie jaoks nginx'i taga, seega aeglaste klientidega mingeid probleeme ei ole. Teiseks, kliendi kanalil on vaht – sisuliselt vĂ”ime sinna paigutada kuni sada uuendust... Kui me ei saa kanalisse kirjutada, siis see kustutab selle. Kui me nĂ€eme, et kanal on blokeeritud, siis lihtsalt sulgeme kanali ja kĂ”ik – klient ĂŒhendub jĂ€lle, kui juhtub mingi probleem. Seega sisuliselt blokeeringud ei teki.

K: – Kas ei saanud kohe saata Listen/Notify kirje, mitte tabeli-identifikaatorit?

MS: – Listen/Notify'l on 8000-baidi piirang eelnevalt laaditavale, mida ta saadab. PĂ”himĂ”tteliselt oleks saanud saata, kui tegeleme vĂ€ikese hulga andmetega, aga mulle tundub, et nii [kui me teeme] on lihtsalt usaldusvÀÀrsem. Piirangud on ise „PostgreSQL'is”.

K: – Kas kliendid saavad uuendusi kohtumistest, mis neid ei huvita?

MS: – Üldiselt jah. Üldiselt on seal paralleelselt 2-3 kohtumist, ja see on pigem harv. Kui klient vaatab midagi, siis tavaliselt vaatab ta just seda kohtumist, mis toimub. Siis on kliendil kohalik andmebaas, kuhu kĂ”ik need uuendused kogutakse, ja isegi ilma internetiĂŒhenduseta saab klient vaadata kĂ”iki möödunud mĂ€nge, mille kohta tal on uuendusi. Sisuliselt 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): – Toona (see oli aasta tagasi) oli ORM-e vĂ€hem, kui nĂŒĂŒd, kui neid on piisavalt palju. Enamik olemasolevatest ORM-idest, mis mulle kĂ”ige vĂ€hem meeldivad, töötavad enamasti tĂŒhipindadega. See tĂ€hendab, et need ORM-id on valmis vĂ”tma vastu kĂ”ike, mis iganes: struktuuri, struktuuri viidat, arvu, midagi, mis ei ole asjaga seotud...

Meie ORM genereerib struktuure andmemudeli pÔhjal. Ise. Ja seega on kÔik meetodid konkreetsed, ei kasuta peegeldust jne. Need vÔtavad vastu struktuurid ja ootavad, et neid struktuure kasutatakse.

K: – Kui palju inimesi osales?

MS: – Algfaasis osales kaks inimest. Kusagil juunis alustasime, augustis oli peamine osa valmis (esimene versioon). Septembris toimus vĂ€ljaanne.

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

MS: Kui rÀÀkida otse, siis SSE on ikkagi html5-protokoll: SSE standard on mĂ”eldud suhtlemiseks brauseritega, nii palju kui ma aru saan. Sellel on lisafunktsioonid, et brauserid saaksid uuesti ĂŒhenduda (ja muud), kuid need pole meile vajalikud, sest meil oli kliente, kes said rakendada mis tahes ĂŒhendamise ja teabe hankimise loogikat. Tegime pigem midagi, mis sarnaneb SSE-le. See ei ole protokoll ise.
Ei olnud vajadust. Nii palju kui ma mĂ”istan, rakendasid kliendid ĂŒhendusmehhanismi peaaegu nullist. Neil ei olnud pĂ”himĂ”tteliselt vahet.

K: Milliseid tÀiendavaid tööriistu te kasutasite?

MS: Kasutame aktiivselt govet ja golint, et stiil oleks ĂŒhtlane, samuti gofmt. Rohkem me midagi ei kasutanud.

K: Kuidas te debugimist tegite?

MS: Debugimine toimus suures osas testide kaudu. Me ei kasutanud mingit debuggerit, GOP-i.

K: Kas saaksite tagastada slaidi, kus on rakendatud funktsioon Publish? Kas ĂŒhenĂ€olised muutujate nimed ei hĂ€iri teid?

MS: Ei. Neil on piisavalt kitsas nĂ€htavus. Nad ei kasutata kuskil mujal kui siin (vĂ€lja arvatud selle klassi sisemuses), ja see on vĂ€ga kompaktne – vĂ”tab vaid 7 rida.

K: Kuid see ei tundu ikkagi intuitiivne...

MS: Ei-ei, see on tĂ”eline kood! Asi ei ole stiilis. Lihtsalt see on selline utilitaarne, tĂ€iesti vĂ€ike klass – vaid 3 vĂ€lja klassi sees...

Mikhail Salosin. Golang Meetup. Go kasutamine rakenduse "Sootri+" tagaplaanil

MS: Suures osas ei muutu kĂ”ik need andmed, mis sĂŒnkroniseeritakse klientidega (hooajalised mĂ€ngud, mĂ€ngijad). Üldiselt öeldes, kui me teeme veel mĂ”nda spordiala, kus tuleb mĂ€ngu muuta, arvestame kĂ”ik uues kliendi versioonis, samas kui vanad kliendi versioonid blokeeritakse.

K: Kas on mingeid kolmandate osapoolte pakette sÔltuvuste haldamiseks?

MS: Kasutame go dep.

K: Ettekanne kÀsitles midagi videot, aga ettekandes videost midagi pole.

MS: Ei, mul ei ole videos midagi ettepanekus. See on nimetatud "Vaata+" – see on rakenduse nimi.

K: Te rÀÀkisite, et see voogedastatakse klientidele?

MS: Me ei tegelenud voogedastava videoga. Selle tegi tÀielikult "MegaFon". Jah, ma ei öelnud, et rakendus on megafooni oma.

MS: – Go – andmete edastamiseks – arve, mĂ€nguĂŒrituste, statistika jms kohta
 Go – see on tĂ€ielik tagumine osa rakendusele. Kliendil peab olema allikas, kust teada saada, millist linki kasutada mĂ€ngu vaatamiseks. Meil on videolinkide ja voogesituste lingid, mis on valmis.

MĂ€ngi videot

Veidi reklaami 🙂

AitÀh, et olete meiega. Kas teile meeldivad meie artiklid? Kas soovite nÀha rohkem huvitavat sisu? Toetage meid, tellides teenuse vÔi soovitades meid tuttavatele. Pilve VPS arendajatele alates $4.99, ainulaadne entry-level 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 jagada serverit Ôigesti? (saadaval RAID1 ja RAID10 variandid, kuni 24 tuuma ja kuni 40GB DDR4).

Dell R730xd on Equinixi Tier IV andmekeskuses Amsterdamis kaks korda odavam? Ainult meie juures 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TB alates $199 Hollandis! Dell R420 — 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — alates $99! Lugege sellest Kuidas luua ettevĂ”tte tasemel infrastruktuuri, kasutades Dell R730xd E5-2650 v4 servereid, mille hind on 9000 eurot, taskukohase hinna eest?

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster