Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

Mihhail Salosin (edaspidi – MS): - Tere kõigile! Minu nimi on Michael. Töötan MC2 Software taustaprogrammi arendajana ja räägin Go kasutamisest Look+ mobiilirakenduse taustaprogrammis.

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

Kas kellelegi siin hoki meeldib?

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

Siis on see rakendus teie jaoks. See on mõeldud Androidile ja iOS-ile ning seda kasutatakse erinevate spordisündmuste ülekannete vaatamiseks võrgus ja salvestamiseks. Rakendus sisaldab ka erinevat statistikat, tekstiülekandeid, konverentside, turniiride tabeleid ja muud fännidele kasulikku teavet.

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

Samuti on rakenduses selline asi nagu videomomendid ehk saad vaadata matšide tähtsamaid momente (väravad, heitlused, löögid jne). Kui te ei soovi kogu saadet vaadata, saate vaadata ainult kõige huvitavamaid.

Mida sa arenduses kasutasid?

Põhiosa oli kirjutatud Go-s. API, millega mobiilikliendid suhtlesid, oli kirjutatud Go-s. Go-sse kirjutati ka teenus push-teadete saatmiseks mobiiltelefonidele. Pidime ka oma ORM-i kirjutama, millest võib-olla kunagi räägime. Noh, Go-s sai kirja mõned väikesed teenused: suuruse muutmine ja piltide laadimine toimetajate jaoks...

Andmebaasina kasutasime PostgreSQL-i. Redigeerija liides on kirjutatud Ruby on Railsis, kasutades ActiveAdmini pärli. Statistika importimine statistika pakkujalt on samuti kirjutatud ruby ​​keeles.

Süsteemi API testide jaoks kasutasime Pythoni unittesti. Memcachedi kasutatakse API maksekõnede piiramiseks, "Chefi" kasutatakse konfiguratsiooni juhtimiseks, Zabbixit kasutatakse süsteemisisese statistika kogumiseks ja jälgimiseks. Graylog2 on logide kogumiseks, Slate on klientidele mõeldud API dokumentatsioon.

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

Protokolli valik

Esimene probleem, millega me kokku puutusime: pidime järgmiste punktide põhjal valima taustaprogrammi ja mobiiliklientide vahelise suhtluse protokolli...

  • Kõige olulisem nõue: klientide andmeid tuleb uuendada reaalajas. See tähendab, et kõik, kes praegu ülekannet vaatavad, peaksid värskendusi saama peaaegu kohe.
  • Asjade lihtsustamiseks eeldasime, et klientidega sünkroonitud andmeid ei kustutata, vaid need peidetakse spetsiaalsete lippude abil.
  • Igasugused haruldased päringud (nagu statistika, meeskonna koosseisud, meeskonna statistika) saadakse tavaliste GET päringutega.
  • Lisaks pidi süsteem hõlpsalt toetama 100 tuhat kasutajat korraga.

Selle põhjal oli meil kaks protokollivalikut:

  1. Veebipistikupesad. Kuid me ei vajanud kanaleid kliendilt serverisse. Meil oli vaja ainult serverist kliendile värskendusi saata, seega on veebisocket üleliigne valik.
  2. Serveri poolt saadetud sündmused (SSE) tulid täpselt välja! See on üsna lihtne ja rahuldab põhimõtteliselt kõike, mida vajame.

Serveri poolt saadetud sündmused

Paar sõna selle kohta, kuidas see asi töötab...

See töötab http-ühenduse peal. Klient saadab päringu, server vastab Content-Type: text/event-stream ja ei katkesta ühendust kliendiga, vaid jätkab andmete kirjutamist ühendust:

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

Andmeid saab saata klientidega kokkulepitud vormingus. Meie puhul saatsime selle sellisel kujul: sündmuse väljale saadeti muudetud struktuuri nimi (isik, mängija) ja andmeväljale JSON koos mängija jaoks uute muudetud väljadega.

Nüüd räägime sellest, kuidas interaktsioon ise toimib.

  • Esimese asjana teeb klient kindlaks, millal viimati teenusega sünkrooniti: ta vaatab oma kohalikku andmebaasi ja määrab viimase salvestatud muudatuse kuupäeva.
  • Ta saadab selle kuupäevaga päringu.
  • Vastuseks saadame talle kõik värskendused, mis on toimunud pärast seda kuupäeva.
  • Pärast seda loob see ühenduse otseülekande kanaliga ja ei sulgu enne, kui vajab järgmisi värskendusi:

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

Saadame talle muudatuste nimekirja: kui keegi lööb värava, muudame matši skoori, kui ta saab vigastada, saadetakse see ka reaalajas. Seega saavad kliendid mängusündmuste voos koheselt ajakohased andmed. Perioodiliselt, et klient saaks aru, et server ei ole surnud, temaga ei juhtunud midagi, saadame iga 15 sekundi tagant ajatempli – et ta teaks, et kõik on korras ja pole vaja uuesti ühendust luua.

Kuidas reaalajas ühendust teenindatakse?

  • Kõigepealt loome kanali, kuhu puhverdatud värskendused vastu võetakse.
  • Pärast seda tellime selle kanali värskenduste saamiseks.
  • Panime õige päise, et klient teaks, et kõik on korras.
  • Saada esimene ping. Salvestame lihtsalt praeguse ühenduse ajatempli.
  • Pärast seda loeme kanalilt tsüklina, kuni uuenduskanal suletakse. Kanal saab perioodiliselt kas praeguse ajatempli või muudatused, mida me juba kirjutame avatud ühendustele.

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

Esimene probleem, millega kokku puutusime, oli järgmine: iga kliendiga avatud ühenduse jaoks lõime taimeri, mis tiksus kord iga 15 sekundi järel - selgub, et kui meil oleks ühe masinaga (ühe API serveriga) avatud 6 tuhat ühendust, siis 6 loodud tuhat taimerit. See viis selleni, et masin ei pidanud nõutavat koormust. Probleem ei olnud meile nii ilmne, kuid saime veidi abi ja parandasime selle.

Selle tulemusena pärineb meie ping nüüd samalt kanalilt, kust värskendus tuleb.

Sellest lähtuvalt on ainult üks taimer, mis tiksub iga 15 sekundi järel.

Siin on mitmeid abifunktsioone - päise saatmine, ping ja struktuur ise. See tähendab, et tabeli nimi (inimene, matš, hooaeg) ja teave selle kande kohta edastatakse siin:

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

Värskenduste saatmise mehhanism

Nüüd natuke sellest, kust muutused tulevad. Meil on mitu inimest, toimetajad, kes vaatavad ülekannet reaalajas. Nad loovad kõik sündmused: keegi saadeti minema, keegi sai vigastada, mingi asendus...

CMS-i abil sisestatakse andmed andmebaasi. Pärast seda teavitab andmebaas sellest API-servereid kuulamise/teavitamise mehhanismi abil. API-serverid saadavad selle teabe juba klientidele. Seega on meil andmebaasiga ühendatud sisuliselt vaid üksikud serverid ja erilist koormust andmebaasile ei ole, kuna klient ei suhtle andmebaasiga kuidagi otse:

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

PostgreSQL: kuula/teavita

Postgresi kuulamise/teavitamise mehhanism võimaldab teavitada sündmuste tellijaid, et mõni sündmus on muutunud – mõni kirje on andmebaasis loodud. Selleks kirjutasime lihtsa päästiku ja funktsiooni:

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

Kirje sisestamisel või muutmisel kutsume välja data_updates kanalil funktsiooni notify, edastades sinna tabeli nime ja muudetud või sisestatud kirje identifikaatori.

Kõikide tabelite jaoks, mis tuleb kliendiga sünkroonida, defineerime trigeri, mis pärast kirje muutmist/värskendamist kutsub välja alloleval slaidil näidatud funktsiooni.
Kuidas API neid muudatusi tellib?

Luuakse Fanouti mehhanism – see saadab kliendile sõnumeid. See kogub kokku kõik kliendikanalid ja saadab nende kanalite kaudu saadud värskendused:

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

Siin kontrollib standardne pq teek, mis ühendub andmebaasiga ja ütleb, et tahab kanalit kuulata (data_updates), et ühendus oleks avatud ja kõik on korras. Jätan ruumi säästmiseks veakontrolli vahele (kontrollimata jätmine on ohtlik).

Järgmisena seadistame asünkroonselt Tickeri, mis saadab iga 15 sekundi järel pingi ja hakkab kuulama tellitud kanalit. Kui saame pingi, avaldame selle pingi. Kui saame mingisuguse sissekande, avaldame selle sissekande kõigile selle Fanouti tellijatele.

Kuidas Fan-out töötab?

Vene keeles tähendab see "jagajat". Meil on üks objekt, mis registreerib abonendid, kes soovivad värskendusi saada. Ja niipea, kui sellele objektile saabub värskendus, levitab see värskendust kõigile oma tellijatele. Piisavalt lihtne:

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

Kuidas seda Go-s rakendatakse:

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

Struktuur on olemas, see sünkroniseeritakse Mutexesi abil. Sellel on väli, mis salvestab Fanouti ühenduse oleku andmebaasiga, st see kuulab hetkel ja saab värskendusi, samuti kõigi saadaolevate kanalite loendi - kaart, mille võtmeks on kanal ja struktuur kujul väärtused (põhimõtteliselt ei kasutata seda mingil viisil).

Kaks meetodit - ühendatud ja lahtiühendatud - võimaldavad meil Fanoutile öelda, et meil on alusega ühendus, see on ilmnenud ja ühendus alusega on katkenud. Teisel juhul peate kõik kliendid lahti ühendama ja ütlema neile, et nad ei saa enam midagi kuulata ja loovad uuesti ühenduse, kuna ühendus nendega on katkenud.

Samuti on olemas tellimismeetod, mis lisab kanali "kuulajate" hulka:

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

On olemas Unsubscribe meetod, mis eemaldab kanali kuulajate hulgast, kui klient ühenduse katkestab, samuti Publish meetod, mis võimaldab saata sõnumi kõigile tellijatele.

Küsimus: – Mida selle kanali kaudu edastatakse?

PRL: – Muudetud mudel või ping edastatakse (sisuliselt ainult arv, täisarv).

PRL: - Saate saata kõike, saata mis tahes struktuuri, avaldada - see muutub lihtsalt JSON-iks ja kõik.

PRL: – Postgresilt saame teate – see sisaldab tabeli nime ja identifikaatorit. Tabeli nime ja identifikaatori põhjal saame vajaliku kirje ning seejärel saadame selle struktuuri avaldamiseks.

Infrastruktuur

Kuidas see infrastruktuuri vaatenurgast välja näeb? Meil on 7 riistvaraserverit: üks neist on täielikult andmebaasile pühendatud, ülejäänud kuus töötavad virtuaalmasinaid. API-st on 6 koopiat: iga API-ga virtuaalne masin töötab eraldi riistvaraserveris – see on töökindluse huvides.

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

Juurdepääsetavuse parandamiseks on meil kaks Keepalivedi installitud esiosa, nii et kui midagi peaks juhtuma, saaks üks esiosa teise asendada. Lisaks – CMS-i kaks koopiat.

Olemas on ka statistika maaletooja. Seal on DB Slave, millest tehakse perioodiliselt varukoopiaid. Seal on rakendus Pigeon Pusher, mis saadab klientidele push-teateid, aga ka infrastruktuuri asju: Zabbix, Graylog2 ja Chef.

Tegelikult on see infrastruktuur üleliigne, sest 100 tuhat saab teenindada vähemate serveritega. Aga rauda oli - kasutasime (meile öeldi, et see on võimalik - miks mitte).

Go plussid

Pärast selle rakenduse kallal töötamist ilmnesid Go sellised ilmsed eelised.

  • Lahe http raamatukogu. Sellega saab karbist päris palju luua.
  • Lisaks kanalid, mis võimaldasid meil väga lihtsalt rakendada mehhanismi klientidele teatiste saatmiseks.
  • Imeline asi, võidusõidudetektor võimaldas meil kõrvaldada mitu kriitilist viga (lavastuse infrastruktuur). Kõik, mis lavastusel töötab, käivitatakse, koostatakse Race võtmega; ja vastavalt sellele saame vaadata lavastuse infrastruktuuri, et näha, millised potentsiaalsed probleemid meil on.
  • Minimalism ja keele lihtsus.

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

Otsime arendajaid! Kui keegi soovib, palun.

küsimused

Küsimus publikult (edaspidi – B): – Mulle tundub, et teil jäi Fan-outiga seoses üks oluline punkt kahe silma vahele. Kas ma saan õigesti aru, et kui saadate kliendile vastuse, siis blokeerite, kui klient ei soovi lugeda?

PRL: - Ei, me ei blokeeri. Esiteks on see kõik meil nginxi taga ehk aeglaste klientidega pole probleeme. Teiseks on kliendil puhvriga kanal - tegelikult saame sinna panna kuni sada uuendust... Kui kanalile kirjutada ei saa, siis kustutab selle ära. Kui näeme, et kanal on blokeeritud, siis sulgeme kanali lihtsalt ja ongi kõik – kui probleem tekib, loob klient uuesti ühenduse. Seetõttu ei ole siin põhimõtteliselt mingit blokeerimist.

Sisse: – Kas kuulamis-/teavitamisfunktsiooni ei oleks võimalik kohe saata kirje, mitte identifikaatoritabel?

PRL: – Kuula/teavitab saadetava eellaadimise piirang 8 tuhat baiti. Põhimõtteliselt oleks võimalik saata, kui oleks tegemist väikese andmehulgaga, aga mulle tundub, et nii [viis, kuidas me seda teeme] on lihtsalt usaldusväärsem. Piirangud on Postgres endas.

Sisse: – Kas kliendid saavad värskendusi matšide kohta, mis neid ei huvita?

PRL: - Üldiselt jah. Paralleelselt toimub reeglina 2-3 matši ja ka siis üsna harva. Kui klient vaatab midagi, siis tavaliselt vaatab ta ka toimuvat matši. Seejärel on kliendil kohalik andmebaas, kuhu kõik need uuendused liidetakse, ja isegi ilma internetiühenduseta saab klient vaadata kõiki varasemaid vasteid, mille kohta tal uuendusi on. Põhimõtteliselt sünkroonime oma serveris oleva andmebaasi kliendi kohaliku andmebaasiga, et ta saaks töötada võrguühenduseta.

Sisse: – Miks te oma ORM-i tegite?

Aleksei (üks Look+ arendajatest): – Tol ajal (see oli aasta tagasi) oli ORM-e vähem kui praegu, mil neid on päris palju. Minu lemmik asi enamiku ORM-ide puhul on see, et enamik neist töötab tühjade liidestega. See tähendab, et nende ORM-ide meetodid on valmis võtma kõike: struktuuri, struktuuri osutit, arvu, midagi täiesti ebaolulist...

Meie ORM genereerib andmemudelil põhinevaid struktuure. mina ise. Ja seetõttu on kõik meetodid konkreetsed, ei kasuta peegeldust jne. Nad aktsepteerivad struktuure ja loodavad kasutada neid struktuure, mis tulevad.

Sisse: - Kui palju inimesi osales?

PRL: – Algetapis osales kaks inimest. Alustasime kuskil juunis ja augustis sai põhiosa valmis (esimene versioon). Septembris ilmus.

Sisse: – Kui kirjeldate SSE-d, ei kasuta te ajalõppu. Miks nii?

PRL: – Ausalt öeldes on SSE ikkagi html5-protokoll: SSE standard on minu arusaamist mööda loodud brauseriga suhtlemiseks. Sellel on lisafunktsioonid, et brauserid saaksid uuesti ühenduse luua (ja nii edasi), kuid me ei vaja neid, sest meil olid kliendid, kes said ühenduse loomiseks ja teabe vastuvõtmiseks rakendada mis tahes loogikat. Me ei teinud SSE-d, vaid pigem midagi SSE-le sarnast. See ei ole protokoll ise.
Polnud vajadust. Minu arusaamist mööda rakendasid kliendid ühendusmehhanismi peaaegu nullist. Nad ei hoolinud sellest tegelikult.

Sisse: – Milliseid täiendavaid utiliite kasutasite?

PRL: – Stiili ühtseks muutmiseks kasutasime kõige aktiivsemalt govet ja golint, samuti gofmt. Midagi muud ei kasutatud.

Sisse: – Mida sa silumiseks kasutasid?

PRL: – Silumine viidi suures osas läbi testide abil. Me ei kasutanud ühtegi silurit ega GOP-i.

Sisse: – Kas saate tagastada slaidi, kus on rakendatud funktsioon Avalda? Kas ühetähelised muutujate nimed ajavad teid segadusse?

PRL: - Ei. Neil on üsna "kitsas" nähtavus. Neid ei kasutata kusagil mujal peale siin (välja arvatud selle klassi sisemised osad) ja see on väga kompaktne - see võtab ainult 7 rida.

Sisse: – Kuidagi pole see ikka veel intuitiivne...

PRL: - Ei, ei, see on tõeline kood! Asi pole stiilis. See on lihtsalt selline utilitaarne, väga väike klass – ainult 3 välja klassi sees...

Mihhail Salosin. Golangi kohtumine. Go kasutamine rakenduse Look+ taustaprogrammis

PRL: – Üldiselt kõik klientidega sünkroonitavad andmed (hooaja mängud, mängijad) ei muutu. Jämedalt öeldes, kui teeme mõne muu spordiala, kus peame matši muutma, võtame kliendi uues versioonis lihtsalt kõike arvesse ja kliendi vanad versioonid keelatakse.

Sisse: – Kas on olemas kolmanda osapoole sõltuvushalduspakette?

PRL: – Me kasutasime go depi.

Sisse: – Raporti teemas oli midagi video kohta, kuid videoteemalises raportis ei olnud midagi.

PRL: – Ei, mul pole selle video teemas midagi. Seda nimetatakse "Look+" - see on rakenduse nimi.

Sisse: – Kas sa ütlesid, et seda voogesitatakse klientidele?

PRL: – Me ei osalenud video voogesituses. Seda tegi täielikult Megafon. Jah, ma ei öelnud, et rakendus oli MegaFon.

PRL: – Go – kõigi andmete saatmiseks – skoor, mängusündmused, statistika... Go on kogu rakenduse taustaprogramm. Klient peab kuskilt teadma, millist linki mängija jaoks kasutada, et kasutaja saaks matši vaadata. Meil on lingid ettevalmistatud videotele ja voogudele.

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