Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

Mikhail Salosin (hér eftir – MS): - Hæ allir! Ég heiti Michael. Ég vinn sem bakendahönnuður hjá MC2 Software og ég mun tala um að nota Go í bakenda Look+ farsímaforritsins.

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

Er einhver hérna sem fílar íshokkí?

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

Þá er þetta forrit fyrir þig. Það er fyrir Android og iOS og er notað til að horfa á útsendingar frá ýmsum íþróttaviðburðum á netinu og taka upp. Forritið inniheldur einnig ýmsa tölfræði, textaútsendingar, töflur fyrir ráðstefnur, mót og aðrar upplýsingar gagnlegar fyrir aðdáendur.

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

Einnig er í forritinu eitthvað eins og myndbandsaugnablik, þ.e. þú getur horft á mikilvægustu augnablik leikja (mörk, bardagar, vítaspyrnukeppni osfrv.). Ef þú vilt ekki horfa á alla útsendinguna geturðu aðeins horft á þá áhugaverðustu.

Hvað notaðir þú í þróun?

Aðalhlutinn var skrifaður í Go. API sem farsímaviðskiptavinir áttu samskipti við var skrifað í Go. Þjónusta til að senda ýtt tilkynningar í farsíma var einnig skrifuð í Go. Við þurftum líka að skrifa okkar eigin ORM, sem við gætum talað um einhvern tíma. Jæja, nokkrar litlar þjónustur voru skrifaðar í Go: breyta stærð og hlaða myndum fyrir ritstjórana...

Við notuðum PostgreSQL sem gagnagrunn. Ritstjóraviðmótið var skrifað í Ruby on Rails með því að nota ActiveAdmin gimsteininn. Innflutningur á tölfræði frá tölfræðiveitu er einnig skrifuð í Ruby.

Fyrir kerfis API próf notuðum við Python unittest. Memcached er notað til að stöðva API greiðslusímtöl, „Chef“ er notað til að stjórna stillingum, Zabbix er notað til að safna og fylgjast með innri kerfistölfræði. Graylog2 er til að safna annálum, Slate er API skjöl fyrir viðskiptavini.

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

Bókunarval

Fyrsta vandamálið sem við lentum í: við þurftum að velja samskiptareglur fyrir samskipti milli bakenda og farsíma viðskiptavina, byggt á eftirfarandi atriðum...

  • Mikilvægasta krafan: gögn um viðskiptavini verða að vera uppfærð í rauntíma. Það er að segja að allir sem eru að horfa á útsendinguna ættu að fá uppfærslur nánast samstundis.
  • Til að einfalda hlutina gerðum við ráð fyrir að gögnum sem eru samstillt við viðskiptavini sé ekki eytt, heldur sé þeim falið með sérstökum fánum.
  • Alls konar sjaldgæfar beiðnir (svo sem tölfræði, liðssamsetning, liðstölfræði) eru fengnar með venjulegum GET beiðnum.
  • Auk þess þurfti kerfið auðveldlega að styðja 100 þúsund notendur á sama tíma.

Byggt á þessu höfðum við tvo samskiptamöguleika:

  1. Veftengi. En við þurftum ekki rásir frá biðlara til netþjóns. Við þurftum aðeins að senda uppfærslur frá þjóninum til viðskiptavinarins, svo nettengi er óþarfi valkostur.
  2. Server-Sent Events (SSE) komu upp alveg rétt! Það er frekar einfalt og uppfyllir í rauninni allt sem við þurfum.

Viðburðir sendir frá þjóni

Nokkur orð um hvernig þetta virkar...

Það keyrir ofan á http tengingu. Viðskiptavinurinn sendir beiðni, þjónninn svarar með Content-Type: text/event-stream og lokar ekki tengingunni við biðlarann ​​heldur heldur áfram að skrifa gögn í tenginguna:

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

Hægt er að senda gögn á því formi sem samið er um við viðskiptavini. Í okkar tilviki sendum við það á þessu formi: nafn breyttrar uppbyggingar (persóna, leikmaður) var sent á viðburðareitinn og JSON með nýjum, breyttum reitum fyrir leikmanninn var sent í gagnareitinn.

Nú skulum við tala um hvernig samspilið sjálft virkar.

  • Það fyrsta sem viðskiptavinurinn gerir er að ákvarða síðast þegar samstilling við þjónustuna var framkvæmd: hann skoðar staðbundinn gagnagrunn sinn og ákvarðar dagsetningu síðustu breytinga sem hann skráði.
  • Það sendir beiðni með þessari dagsetningu.
  • Sem svar sendum við honum allar uppfærslur sem hafa átt sér stað síðan þann dag.
  • Eftir það tengist það rásinni í beinni og lokar ekki fyrr en það þarf þessar uppfærslur:

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

Við sendum honum lista yfir breytingar: ef einhver skorar mark breytum við markatölu leiksins, ef hann meiðist er þetta líka sent í rauntíma. Þannig fá viðskiptavinir samstundis uppfærð gögn í straumi leikviðburða. Reglulega, svo að viðskiptavinurinn skilji að þjónninn hafi ekki dáið, að ekkert hafi gerst við hann, sendum við tímastimpil á 15 sekúndna fresti - svo hann viti að allt sé í lagi og engin þörf á að tengjast aftur.

Hvernig er beinni tengingunni þjónustað?

  • Fyrst af öllu búum við til rás þar sem biðminni uppfærslur verða mótteknar.
  • Eftir það gerumst við áskrifandi að þessari rás til að fá uppfærslur.
  • Við stillum réttan haus þannig að viðskiptavinurinn viti að allt sé í lagi.
  • Sendu fyrsta pingið. Við skráum einfaldlega núverandi tengingartímastimpil.
  • Eftir það lesum við af rásinni í lykkju þar til uppfærslurásinni er lokað. Rásin fær reglulega annað hvort núverandi tímastimpil eða breytingar sem við erum nú þegar að skrifa til að opna tengingar.

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

Fyrsta vandamálið sem við lentum í var eftirfarandi: fyrir hverja tengingu sem var opnuð við biðlarann ​​bjuggum við til tímamælir sem tikkaði einu sinni á 15 sekúndna fresti - það kemur í ljós að ef við hefðum 6 þúsund tengingar opnar með einni vél (með einum API netþjóni), 6 þúsund tímamælir voru búnir til. Þetta leiddi til þess að vélin hélt ekki tilskildu álagi. Vandamálið var ekki svo augljóst fyrir okkur en við fengum smá hjálp og redduðum því.

Fyrir vikið kemur nú pingið okkar frá sömu rás og uppfærslan kemur frá.

Samkvæmt því er aðeins einn tímamælir sem tikkar einu sinni á 15 sekúndna fresti.

Það eru nokkrar aukaaðgerðir hér - að senda hausinn, pingið og uppbyggingin sjálf. Það er að segja, nafn töflunnar (persóna, leikur, leiktíð) og upplýsingar um þessa færslu eru sendar hér:

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

Vélbúnaður til að senda uppfærslur

Nú aðeins um hvaðan breytingarnar koma. Við erum með nokkra aðila, ritstjóra, sem horfa á útsendinguna í rauntíma. Þeir skapa alla atburðina: einhver var rekinn af velli, einhver meiddist, einhvers konar varamaður...

Með því að nota CMS fara gögn inn í gagnagrunninn. Eftir þetta lætur gagnagrunnurinn API-þjónum vita um þetta með því að nota Listen/Tilkynna vélbúnaðinn. API netþjónar senda nú þegar þessar upplýsingar til viðskiptavina. Þannig höfum við í rauninni aðeins nokkra netþjóna tengda gagnagrunninum og það er ekkert sérstakt álag á gagnagrunninn, vegna þess að viðskiptavinurinn hefur ekki samskipti beint við gagnagrunninn á nokkurn hátt:

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

PostgreSQL: Hlustaðu / Láta vita

Hlusta/Tilkynna vélbúnaðurinn í Postgres gerir þér kleift að láta áskrifendur viðburða vita að einhver atburður hafi breyst - einhver skrá hefur verið búin til í gagnagrunninum. Til að gera þetta skrifuðum við einfaldan kveikju og aðgerð:

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

Þegar skrá er sett inn eða breytt, köllum við tilkynningaraðgerðina á data_updates rásinni og sendum þangað nafn töflunnar og auðkenni færslunnar sem var breytt eða sett inn.

Fyrir allar töflur sem þarf að samstilla við biðlarann, skilgreinum við kveikju, sem, eftir að hafa breytt / uppfært skrá, kallar á aðgerðina sem tilgreind er á glærunni hér að neðan.
Hvernig gerist API áskrifandi að þessum breytingum?

Fanout vélbúnaður er búinn til - það sendir skilaboð til viðskiptavinarins. Það safnar öllum rásum viðskiptavina og sendir uppfærslur sem það fékk í gegnum þessar rásir:

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

Hér er staðlað pq library, sem tengist gagnagrunninum og segir að það vilji hlusta á rásina (data_updates), að tengingin sé opin og allt sé í lagi. Ég er að sleppa villuskoðun til að spara pláss (ekki athuga er hættulegt).

Næst stillum við ósamstillt Ticker, sem mun senda ping á 15 sekúndna fresti, og byrjum að hlusta á rásina sem við gerumst áskrifendur að. Ef við fáum ping birtum við þetta ping. Ef við fáum einhvers konar færslu, þá birtum við þessa færslu til allra áskrifenda þessa Fanout.

Hvernig virkar Fan-out?

Á rússnesku þýðir þetta sem „kljúfur“. Við erum með einn hlut sem skráir áskrifendur sem vilja fá einhverjar uppfærslur. Og um leið og uppfærsla berst fyrir þennan hlut, dreifir það þessari uppfærslu til allra áskrifenda sinna. Nógu einfalt:

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

Hvernig það er útfært í Go:

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

Það er uppbygging, það er samstillt með Mutexes. Það er með reit sem vistar stöðu tengingar Fanout við gagnagrunninn, þ.e.a.s. það er að hlusta og mun fá uppfærslur, auk lista yfir allar tiltækar rásir - kort, lykillinn að því er rásin og uppsetningin í formi gildi (í meginatriðum er það ekki notað á nokkurn hátt).

Tvær aðferðir - Tengdur og ótengdur - leyfa okkur að segja Fanout að við séum með tengingu við stöðina, hún hafi birst og að tengingin við stöðina hafi verið rofin. Í öðru tilvikinu þarftu að aftengja alla viðskiptavini og segja þeim að þeir geti ekki lengur hlustað á neitt og að þeir tengist aftur vegna þess að tengingin við þá hafi lokað.

Það er líka til áskriftaraðferð sem bætir rásinni við „hlustendur“:

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

Það er til Unsubscribe aðferð, sem fjarlægir rásina frá hlustendum ef viðskiptavinurinn aftengir sig, sem og Publish aðferð, sem gerir þér kleift að senda skilaboð til allra áskrifenda.

Spurning: – Hvað er sent í gegnum þessa rás?

FRÖKEN: – Líkanið sem hefur breyst eða ping er sent (í rauninni bara tala, heiltala).

FRÖKEN: - Þú getur sent hvað sem er, sent hvaða uppbyggingu sem er, birt það - það breytist bara í JSON og það er það.

FRÖKEN: – Við fáum tilkynningu frá Postgres – hún inniheldur töfluheiti og auðkenni. Út frá töfluheiti og auðkenni fáum við skrána sem við þurfum og sendum síðan þessa uppbyggingu til birtingar.

Infrastructure

Hvernig lítur þetta út frá sjónarhóli innviða? Við erum með 7 vélbúnaðarþjóna: einn þeirra er algjörlega tileinkaður gagnagrunninum, hinir sex keyra sýndarvélar. Það eru 6 eintök af API: hver sýndarvél með API keyrir á sérstökum vélbúnaðarþjóni - þetta er fyrir áreiðanleika.

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

Við erum með tvo framenda með Keepalived uppsettum til að bæta aðgengi, þannig að ef eitthvað gerist getur annar framhliðin komið í stað hinnar. Einnig - tvö eintök af CMS.

Það er líka tölfræðiinnflytjandi. Það er til DB-þræll sem afrit er gert úr reglulega. Það er Pigeon Pusher, forrit sem sendir ýttu tilkynningar til viðskiptavina, auk innviða: Zabbix, Graylog2 og Chef.

Reyndar er þessi innviði óþarfur, því hægt er að þjóna 100 þúsund með færri netþjónum. En það var járn - við notuðum það (var sagt að það væri hægt - hvers vegna ekki).

Kostir Go

Eftir að við unnum að þessu forriti komu svo augljósir kostir Go í ljós.

  • Flott http bókasafn. Með því er hægt að búa til talsvert úr kassanum.
  • Auk þess rásir sem gerðu okkur kleift að innleiða mjög auðveldlega kerfi til að senda tilkynningar til viðskiptavina.
  • Hinn dásamlegi Race skynjari gerði okkur kleift að útrýma nokkrum mikilvægum villum (sviðsetningarinnviði). Allt sem virkar við sviðsetningu er sett í gang, sett saman með Race lyklinum; og við, í samræmi við það, getum skoðað sviðsetningarinnviðina til að sjá hvaða hugsanleg vandamál við höfum.
  • Naumhyggja og einfaldleiki tungumálsins.

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

Við erum að leita að forriturum! Ef einhver vill, vinsamlegast.

spurningar

Spurning frá áhorfendum (hér eftir – B): – Mér sýnist að þú hafir misst af einu mikilvægu atriði varðandi Fan-out. Er ég rétt að skilja að þegar þú sendir svar til viðskiptavinar þá lokar þú ef viðskiptavinurinn vill ekki lesa?

FRÖKEN: - Nei, við erum ekki að loka. Í fyrsta lagi höfum við allt þetta á bak við nginx, það er, það eru engin vandamál með hæga viðskiptavini. Í öðru lagi er viðskiptavinurinn með rás með biðminni - í raun getum við sett allt að hundrað uppfærslur þar... Ef við getum ekki skrifað á rásina þá eyðir hún henni. Ef við sjáum að rásin er lokuð, þá munum við einfaldlega loka rásinni, og það er það - viðskiptavinurinn mun tengjast aftur ef einhver vandamál koma upp. Þess vegna er í grundvallaratriðum engin hindrun hér.

IN: – Gæti ekki verið hægt að senda færslu strax á Listen/Tilkynna, en ekki auðkennistöflu?

FRÖKEN: – Listen/Tilkynna hefur 8 þúsund bæti takmörk á forhleðslunni sem það sendir. Í grundvallaratriðum væri hægt að senda ef við værum að fást við lítið magn af gögnum, en mér sýnist að þessi leið [svo sem við gerum það] sé einfaldlega áreiðanlegri. Takmarkanir eru í Postgres sjálfu.

IN: – Fá viðskiptavinir uppfærslur um leiki sem þeir hafa ekki áhuga á?

FRÖKEN: - Almennt séð, já. Að jafnaði eru 2-3 leikir í gangi samhliða, og jafnvel þá frekar sjaldan. Ef viðskiptavinur er að horfa á eitthvað, þá er hann venjulega að horfa á leikinn sem er í gangi. Síðan hefur viðskiptavinurinn staðbundinn gagnagrunn sem allar þessar uppfærslur eru settar saman í, og jafnvel án nettengingar getur viðskiptavinurinn skoðað allar fyrri samsvörun sem hann hefur uppfærslur fyrir. Í meginatriðum samstillum við gagnagrunninn okkar á þjóninum við staðbundinn gagnagrunn viðskiptavinarins svo hann geti unnið án nettengingar.

IN: – Af hverju bjóstu til þinn eigin ORM?

Alexey (einn af hönnuðum Look+): – Á þeim tíma (það var fyrir ári) voru færri ORM en núna, þegar þeir eru frekar margir. Uppáhalds hlutur minn við flestar ORMs þarna úti er að flestir þeirra keyra á tómum viðmótum. Það er að segja að aðferðirnar í þessum ORM eru tilbúnar til að taka á móti hverju sem er: uppbyggingu, byggingarbendill, tala, eitthvað sem er algjörlega óviðkomandi...

ORM okkar býr til mannvirki byggð á gagnalíkaninu. Sjálfur. Og því eru allar aðferðir steinsteyptar, nota ekki spegilmynd o.s.frv.. Þeir taka við mannvirkjum og ætlast til að nota þau mannvirki sem koma.

IN: — Hversu margir tóku þátt?

FRÖKEN: - Á upphafsstigi tóku tveir þátt. Við byrjuðum einhvers staðar í júní og í ágúst var aðalhlutinn tilbúinn (fyrsta útgáfan). Það kom út í september.

IN: – Þar sem þú lýsir SSE, notarðu ekki timeout. Afhverju er það?

FRÖKEN: – Til að vera heiðarlegur, SSE er enn html5 samskiptareglur: SSE staðallinn er hannaður til að eiga samskipti við vafra, eftir því sem ég skil. Það hefur viðbótareiginleika svo að vafrar geti tengst aftur (og svo framvegis), en við þurfum þá ekki, vegna þess að við vorum með viðskiptavini sem gátu innleitt hvaða rökfræði sem er til að tengjast og taka á móti upplýsingum. Við gerðum ekki SSE, heldur eitthvað svipað og SSE. Þetta er ekki samskiptareglan sjálf.
Það var engin þörf. Eftir því sem ég skil, innleiddu viðskiptavinir tengibúnaðinn nánast frá grunni. Þeim var alveg sama.

IN: – Hvaða viðbótarveitur notaðir þú?

FRÖKEN: – Við notuðum mest govet og golint til að sameina stílinn, sem og gofmt. Ekkert annað var notað.

IN: – Hvað notaðirðu til að kemba?

FRÖKEN: – Villuleit fór að mestu fram með prófum. Við notuðum hvorki villuleit né GOP.

IN: – Geturðu skilað glærunni þar sem Birta aðgerðin er útfærð? Gera eins stafs breytuheiti rugla þig?

FRÖKEN: - Nei. Þeir hafa nokkuð „þröngt“ sýnileikasvið. Þeir eru hvergi notaðir annars staðar nema hér (nema innri hluti þessa flokks), og hann er mjög þéttur - hann tekur aðeins 7 línur.

IN: - Einhvern veginn er það samt ekki leiðandi...

FRÖKEN: - Nei, nei, þetta er alvöru kóða! Þetta snýst ekki um stíl. Þetta er bara svo hagnýtur, mjög lítill bekkur - aðeins 3 reitir inni í bekknum...

Mikhail Salosin. Golang Meetup. Notkun Go í bakenda Look+ forritsins

FRÖKEN: - Í stórum dráttum breytast ekki öll gögn sem eru samstillt við viðskiptavini (tímabilsleikir, leikmenn). Í grófum dráttum, ef við gerum aðra íþrótt þar sem við þurfum að breyta leiknum, þá tökum við einfaldlega allt með í reikninginn í nýju útgáfunni af viðskiptavininum og gömlu útgáfurnar af viðskiptavininum verða bannaðar.

IN: – Eru til einhverjir ósjálfstæðisstjórnunarpakkar frá þriðja aðila?

FRÖKEN: – Við notuðum go dep.

IN: - Það var eitthvað um myndband í efni skýrslunnar, en það var ekkert í skýrslunni um myndband.

FRÖKEN: – Nei, ég hef ekkert í efninu um myndbandið. Það heitir „Look+“ - það er nafnið á forritinu.

IN: – Þú sagðir að það væri streymt til viðskiptavina? ..

FRÖKEN: - Við tókum ekki þátt í að streyma myndbandi. Þetta var algjörlega gert af Megafon. Já, ég sagði ekki að forritið væri MegaFon.

FRÖKEN: – Go – til að senda öll gögn – um stig, um viðburði í leikjum, tölfræði... Go er allt bakhlið forritsins. Viðskiptavinurinn verður að vita einhvers staðar hvaða tengil hann á að nota fyrir leikmanninn svo notandinn geti horft á leikinn. Við erum með tengla á myndbönd og strauma sem hafa verið útbúin.

Nokkrar auglýsingar 🙂

Þakka þér fyrir að vera hjá okkur. Líkar þér við greinarnar okkar? Viltu sjá meira áhugavert efni? Styðjið okkur með því að leggja inn pöntun eða mæla með því við vini, cloud VPS fyrir forritara frá $4.99, einstök hliðstæða upphafsþjóna, sem var fundið upp af okkur fyrir þig: Allur sannleikurinn um VPS (KVM) E5-2697 v3 (6 kjarna) 10GB DDR4 480GB SSD 1Gbps frá $19 eða hvernig á að deila netþjóni? (fáanlegt með RAID1 og RAID10, allt að 24 kjarna og allt að 40GB DDR4).

Dell R730xd 2x ódýrari í Equinix Tier IV gagnaveri í Amsterdam? Aðeins hér 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 sjónvarp frá $199 í Hollandi! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - frá $99! Lestu um Hvernig á að byggja upp infrastructure Corp. flokki með notkun Dell R730xd E5-2650 v4 netþjóna að verðmæti 9000 evrur fyrir eyri?

Heimild: www.habr.com

Bæta við athugasemd