Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

Михаил Салосин (бұдан әрі – МС): - Бәріңе сәлем! Менің атым Майкл. Мен MC2 бағдарламалық жасақтамасында бэк-энд әзірлеушісі ретінде жұмыс істеймін және Go қолданбасын Look+ мобильді қосымшасының бэкендінде пайдалану туралы айтатын боламын.

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

Мұнда хоккейді ұнататындар бар ма?

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

Онда бұл қолданба сізге арналған. Ол Android және iOS жүйесіне арналған және әртүрлі спорттық іс-шаралардың трансляцияларын онлайн және жазылған көру үшін қолданылады. Қосымшада әртүрлі статистика, мәтіндік хабарлар, конференцияларға, турнирлерге арналған кестелер және жанкүйерлер үшін пайдалы басқа да ақпарат бар.

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

Сондай-ақ қосымшада бейне сәттері сияқты нәрсе бар, яғни сіз матчтардың ең маңызды сәттерін (голдар, жекпе-жек, ​​бұлтылар және т.б.) көре аласыз. Егер сіз трансляцияны толығымен көргіңіз келмесе, ең қызықтыларын ғана көре аласыз.

Сіз дамуда не қолдандыңыз?

Негізгі бөлім Go тілінде жазылған. Мобильді клиенттер байланысатын API Go бағдарламасында жазылған. Сондай-ақ Go-да ұялы телефондарға push-хабарламалар жіберу қызметі жазылған. Біз сондай-ақ бір күні сөйлесуіміз мүмкін жеке ORM жазуымыз керек еді. Go бағдарламасында кейбір шағын қызметтер жазылған: редакторлар үшін кескіндердің өлшемін өзгерту және жүктеу...

Біз PostgreSQL дерекқоры ретінде қолдандық. Редактор интерфейсі Ruby on Rails тілінде ActiveAdmin асыл тасты пайдаланып жазылған. Статистика провайдерінен статистиканы импорттау да Ruby тілінде жазылған.

Жүйелік API сынақтары үшін біз Python unittest қолдандық. Memcached API төлем қоңырауларын азайту үшін пайдаланылады, «Аспаз» конфигурацияны басқару үшін пайдаланылады, Zabbix ішкі жүйе статистикасын жинау және бақылау үшін қолданылады. Graylog2 журналдарды жинауға арналған, Slate — клиенттерге арналған API құжаттамасы.

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

Протоколды таңдау

Бізге тап болған бірінші мәселе: бізге келесі тармақтарға сүйене отырып, сервер мен мобильді клиенттер арасындағы өзара әрекеттесу протоколын таңдау керек болды...

  • Ең маңызды талап: клиенттер туралы деректер нақты уақыт режимінде жаңартылуы керек. Яғни, қазір трансляцияны көріп отырған әрбір адам дерлік жаңартуларды алуы керек.
  • Істерді жеңілдету үшін біз клиенттермен синхрондалған деректер жойылмайды, бірақ арнайы жалаушалар арқылы жасырылады деп ойладық.
  • Сирек кездесетін сұраулардың барлық түрлері (мысалы, статистика, команда құрамы, команда статистикасы) қарапайым GET сұраулары арқылы алынады.
  • Сонымен қатар, жүйе бір уақытта 100 мың пайдаланушыны оңай қолдауы керек болды.

Осының негізінде бізде екі протокол опциясы болды:

  1. Websockets. Бірақ бізге клиенттен серверге дейінгі арналар қажет емес еді. Бізге серверден клиентке жаңартуларды жіберу ғана қажет болды, сондықтан веб-розеткалар артық опция болып табылады.
  2. Серверден жіберілген оқиғалар (SSE) дәл келді! Бұл өте қарапайым және негізінен бізге қажет нәрсенің бәрін қанағаттандырады.

Серверден жіберілген оқиғалар

Бұл нәрсе қалай жұмыс істейтіні туралы бірнеше сөз ...

Ол http қосылымының үстінде жұмыс істейді. Клиент сұрау жібереді, сервер Content-Type: text/event-stream арқылы жауап береді және клиентпен байланысты жаппайды, бірақ қосылымға деректерді жазуды жалғастырады:

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

Деректерді клиенттермен келісілген форматта жіберуге болады. Біздің жағдайда біз оны осы пішінде жібердік: өзгертілген құрылымның атауы (адам, ойыншы) оқиға өрісіне жіберілді, ал деректер өрісіне ойыншы үшін жаңа, өзгертілген өрістері бар JSON жіберілді.

Енді өзара әрекеттестіктің өзі қалай жұмыс істейтіні туралы сөйлесейік.

  • Клиент бірінші орындайтын нәрсе - қызметпен синхрондаудың соңғы рет орындалған уақытын анықтау: ол өзінің жергілікті дерекқорын қарап, ол жазған соңғы өзгерту күнін анықтайды.
  • Ол осы күнмен сұрау жібереді.
  • Жауап ретінде біз оған сол күннен бастап болған барлық жаңартуларды жібереміз.
  • Осыдан кейін ол тікелей арнаға қосылып, мына жаңартуларды қажет етпейінше жабылмайды:

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

Біз оған өзгерістер тізімін жібереміз: егер біреу гол соқса, матчтың есебін өзгертеміз, егер ол жарақат алса, бұл да нақты уақытта жіберіледі. Осылайша, клиенттер матч оқиғалары арнасында жаңартылған деректерді лезде алады. Мерзімді түрде, клиент сервердің өлмегенін, оған ештеңе болмағанын түсінуі үшін біз әр 15 секунд сайын уақыт белгісін жібереміз - ол бәрі тәртіппен екенін және қайта қосылудың қажеті жоқ екенін біледі.

Тікелей қосылымға қалай қызмет көрсетіледі?

  • Ең алдымен, біз буферленген жаңартулар қабылданатын арна жасаймыз.
  • Осыдан кейін біз жаңартуларды алу үшін осы арнаға жазыламыз.
  • Клиент бәрі дұрыс екенін білуі үшін біз дұрыс тақырыпты орнаттық.
  • Бірінші пингті жіберіңіз. Біз жай ғана ағымдағы қосылым уақыт белгісін жазамыз.
  • Осыдан кейін біз жаңарту арнасы жабылғанша арнадан циклде оқимыз. Арна мерзімді түрде ағымдағы уақыт белгісін немесе біз ашық қосылымдарға жазып жатқан өзгерістерді қабылдайды.

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

Біз кездестірген бірінші мәселе келесідей болды: клиентпен ашылған әрбір қосылым үшін біз 15 секунд сайын белгі қоятын таймер жасадық - егер бізде бір машинамен (бір API серверімен) 6 мың қосылым ашылған болса, 6 болатыны белгілі болды. мың таймерлер жасалды. Бұл машинаның қажетті жүктемені ұстамауына әкелді. Мәселе бізге соншалықты айқын емес еді, бірақ біз аздап көмек алып, оны жөндедік.

Нәтижесінде, енді біздің пинг жаңарту қай арнадан келеді.

Тиісінше, 15 секунд сайын бір рет белгі беретін бір ғана таймер бар.

Мұнда бірнеше көмекші функциялар бар - тақырыпты, пингті және құрылымның өзін жіберу. Яғни кестенің аты (адам, матч, маусым) және осы жазба туралы ақпарат осында беріледі:

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

Жаңартуларды жіберу механизмі

Енді өзгерістердің қайдан келетіні туралы аздап. Бізде трансляцияны нақты уақытта қарайтын бірнеше адам, редакторлар бар. Олар барлық оқиғаларды жасайды: біреу алаңнан қуылды, біреу жарақат алды, қандай да бір ауыстыру...

CMS көмегімен деректер дерекқорға енгізіледі. Осыдан кейін дерекқор Тыңдау/Хабарлау механизмі арқылы API серверлеріне бұл туралы хабарлайды. API серверлері бұл ақпаратты клиенттерге жіберіп қойған. Осылайша, бізде дерекқорға қосылған бірнеше сервер ғана бар және дерекқорда арнайы жүктеме жоқ, өйткені клиент ешқандай жолмен дерекқормен тікелей әрекеттеспейді:

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

PostgreSQL: тыңдау/хабарландыру

Postgres-тегі Тыңдау/Хабарлау механизмі оқиға жазылушыларына кейбір оқиғалардың өзгергені туралы хабарлауға мүмкіндік береді - дерекқорда кейбір жазбалар жасалған. Ол үшін біз қарапайым триггер мен функцияны жаздық:

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

Жазбаны кірістіру немесе өзгерту кезінде біз кестенің атауын және өзгертілген немесе енгізілген жазбаның идентификаторын жібере отырып, data_updates арнасында ескерту функциясын шақырамыз.

Клиентпен синхрондалу керек барлық кестелер үшін біз жазбаны өзгерткеннен/жаңартқаннан кейін төмендегі слайдта көрсетілген функцияны шақыратын триггерді анықтаймыз.
API бұл өзгерістерге қалай жазылады?

Fanout механизмі жасалады - ол клиентке хабарламалар жібереді. Ол барлық тұтынушы арналарын жинайды және осы арналар арқылы алынған жаңартуларды жібереді:

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

Мұнда деректер базасына қосылатын және арнаны (data_updates) тыңдағысы келетінін айтатын стандартты pq кітапханасы қосылымның ашық екенін және бәрі жақсы екенін тексереді. Мен орынды үнемдеу үшін қатені тексеруді өткізіп жіберемін (тексермеу қауіпті).

Әрі қарай, біз әр 15 секунд сайын пинг жіберетін Ticker-ді асинхронды түрде орнатамыз және біз жазылған арнаны тыңдай бастаймыз. Егер біз пинг алсақ, біз бұл пингті жариялаймыз. Егер біз қандай да бір жазбаны алсақ, біз бұл жазбаны осы Fanout-тың барлық жазылушыларына жариялаймыз.

Fan-out қалай жұмыс істейді?

Орыс тілінде бұл «бөлгіш» деп аударылады. Бізде кейбір жаңартуларды алғысы келетін жазылушыларды тіркейтін бір нысан бар. Осы нысанға жаңарту келген бойда ол бұл жаңартуды өзінің барлық жазылушыларына таратады. Жеткілікті қарапайым:

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

Ол Go бағдарламасында қалай жүзеге асырылады:

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

Құрылымы бар, ол Mutex көмегімен синхрондалады. Оның Fanout-тың дерекқорға қосылу күйін сақтайтын өрісі бар, яғни ол қазіргі уақытта тыңдауда және жаңартуларды алады, сонымен қатар барлық қолжетімді арналардың тізімі - карта, оның кілті арна және түрдегі құрылым болып табылады. мәндер (негізінен ол ешқандай жолмен пайдаланылмайды).

Екі әдіс - Қосылған және Ажыратылған - Fanout-қа бізде базаға қосылым бар екенін, оның пайда болғанын және базаға қосылудың үзілгенін айтуға мүмкіндік береді. Екінші жағдайда, барлық клиенттерді ажыратып, оларға енді ештеңені тыңдай алмайтынын және олармен байланыс жабылғандықтан қайта қосылатынын айту керек.

Арнаны «тыңдаушыларға» қосатын Жазылу әдісі де бар:

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

Клиент ажыратылған жағдайда тыңдаушылардан арнаны алып тастайтын Жазылымнан бас тарту әдісі, сондай-ақ барлық жазылушыларға хабарлама жіберуге мүмкіндік беретін Жариялау әдісі бар.

Сұрақ: – Бұл арна арқылы не беріледі?

ХАНЫМ: – Өзгерген немесе пинг жіберілген модель (негізінен жай сан, бүтін сан).

ХАНЫМ: – Сіз кез келген нәрсені жібере аласыз, кез келген құрылымды жібере аласыз, оны жариялай аласыз – ол жай ғана JSON-ға айналады және солай.

ХАНЫМ: – Біз Postgres-тен хабарландыру аламыз – онда кесте атауы мен идентификатор бар. Кесте атауы мен идентификатор негізінде біз қажетті жазбаны аламыз, содан кейін бұл құрылымды жариялауға жібереміз.

Инфрақұрылым

Бұл инфрақұрылым тұрғысынан қалай көрінеді? Бізде 7 аппараттық сервер бар: олардың біреуі толығымен дерекқорға арналған, қалған алтауы виртуалды машиналарды басқарады. API-ның 6 данасы бар: API бар әрбір виртуалды машина жеке аппараттық серверде жұмыс істейді - бұл сенімділік үшін.

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

Қол жетімділікті жақсарту үшін бізде Keepalived орнатылған екі интерфейс бар, осылайша бірдеңе орын алса, бір интерфейс екіншісін алмастыра алады. Сондай-ақ – CMS екі данасы.

Сондай-ақ статистиканы импорттаушы бар. Сақтық көшірмелері мерзімді түрде жасалатын DB Slave бар. Клиенттерге push хабарландыруларын жіберетін Pigeon Pusher қолданбасы, сонымен қатар инфрақұрылымдық заттар бар: Zabbix, Graylog2 және Chef.

Шын мәнінде, бұл инфрақұрылым артық, өйткені 100 мыңға аз серверлермен қызмет көрсетуге болады. Бірақ темір болды - біз оны қолдандық (бізге бұл мүмкін екенін айтты - неге болмайды).

Go артықшылығы

Біз осы қолданбада жұмыс істегеннен кейін Go-ның осындай айқын артықшылықтары пайда болды.

  • Керемет http кітапханасы. Оның көмегімен сіз қораптан көп нәрсені жасай аласыз.
  • Сонымен қатар, клиенттерге хабарландырулар жіберу механизмін оңай енгізуге мүмкіндік беретін арналар.
  • Жарыс детекторының керемет нәрсесі бізге бірнеше маңызды қателерді жоюға мүмкіндік берді (инфрақұрылымды орналастыру). Сахналауда жұмыс істейтін барлық нәрсе Race пернесі арқылы құрастырылған іске қосылады; және біз, сәйкесінше, бізде қандай ықтимал проблемалар бар екенін көру үшін сахналық инфрақұрылымды қарастыра аламыз.
  • Минимализм және тілдің қарапайымдылығы.

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

Біз әзірлеушілерді іздейміз! Кім қаласа, өтінемін.

Сіздің сұрақтарыңыз

Көрермендер сұрағы (бұдан әрі – Б): – Меніңше, сіз Fan-out-қа қатысты бір маңызды мәселені жіберіп алған сияқтысыз. Клиентке жауап жіберген кезде, егер клиент оқығысы келмесе, блоктайтыныңызды түсінгенім дұрыс па?

ХАНЫМ: – Жоқ, біз бөгет жасап жатқан жоқпыз. Біріншіден, бізде nginx-тің артында осының бәрі бар, яғни баяу клиенттермен проблемалар жоқ. Екіншіден, клиенттің буфері бар арнасы бар - шын мәнінде, біз онда жүзге дейін жаңартулар жасай аламыз... Егер біз арнаға жаза алмасақ, ол оны жояды. Егер біз арнаның бұғатталғанын көрсек, онда біз арнаны жай ғана жабамыз, және бұл - кез келген мәселе туындаған жағдайда клиент қайта қосылады. Сондықтан, негізінен, бұл жерде тосқауыл жоқ.

Q: – Идентификаторлар кестесін емес, Тыңдау/Хабарлау функциясына жазбаны дереу жіберу мүмкін емес пе?

ХАНЫМ: – Тыңдау/Хабарлаудың ол жіберетін алдын ала жүктеуде 8 мың байт шегі бар. Негізінде, егер біз деректердің аз көлемімен айналысатын болсақ, жіберуге болады, бірақ менің ойымша, бұл [біз оны жасау тәсілі] сенімдірек. Шектеулер Postgres-тің өзінде.

Q: – Клиенттер оларды қызықтырмайтын матчтар туралы жаңартуларды ала ма?

ХАНЫМ: - Жалпы, иә. Әдетте, 2-3 матч қатар жүреді, тіпті сирек. Егер клиент бірдеңені көріп отырса, әдетте ол болып жатқан матчты көреді. Содан кейін клиентте барлық осы жаңартулар қосылатын жергілікті дерекқор бар және тіпті Интернет қосылымынсыз клиент өзінің жаңартулары бар барлық өткен сәйкестіктерді көре алады. Негізінде, біз сервердегі дерекқорымызды клиенттің жергілікті дерекқорымен синхрондаймыз, сонда ол желіден тыс жұмыс істей алады.

Q: – Неліктен сіз өзіңіздің ORM-ңызды жасадыңыз?

Алексей (Look+ әзірлеушілерінің бірі): – Ол кезде (бір жыл бұрын) қазіргіге қарағанда ОРМ-лар аз болды, олар өте көп. Көптеген ORMs туралы менің сүйікті нәрсем - олардың көпшілігі бос интерфейстерде жұмыс істейді. Яғни, бұл ORM-дегі әдістер кез келген нәрсені қабылдауға дайын: құрылым, құрылым көрсеткіші, сан, мүлдем қатысы жоқ нәрсе...

Біздің ORM деректер үлгісіне негізделген құрылымдарды жасайды. Өзім. Сондықтан барлық әдістер нақты, шағылыстырмайды және т.б.. Олар құрылымдарды қабылдайды және келген құрылымдарды пайдалануды күтеді.

Q: – Қанша адам қатысты?

ХАНЫМ: – Бастапқы кезеңде екі адам қатысты. Біз маусым айында бір жерде бастадық, ал тамызда негізгі бөлігі дайын болды (бірінші нұсқа). Қыркүйек айында шығарылым болды.

Q: – SSE сипаттайтын жерде сіз күту уақытын қолданбайсыз. Неге бұлай?

ХАНЫМ: – Шынымды айтсам, SSE әлі де html5 протоколы болып табылады: SSE стандарты менің түсінуімше браузерлермен байланысуға арналған. Оның қосымша мүмкіндіктері бар, осылайша браузерлер қайта қосыла алады (және т.б.), бірақ бізге олар қажет емес, өйткені бізде ақпаратты қосу және қабылдаудың кез келген логикасын жүзеге асыра алатын клиенттер болды. Біз SSE емес, SSE-ге ұқсас нәрсені жасадық. Бұл хаттаманың өзі емес.
Қажет болған жоқ. Менің түсінуімше, клиенттер қосылу механизмін нөлден бастап іске асырды. Олар шынымен де мән бермеді.

Q: – Қандай қосымша утилиталарды пайдаландыңыз?

ХАНЫМ: – Стильді біртұтас ету үшін біз govet пен голинтты, сондай-ақ гофмтты белсенді түрде қолдандық. Басқа ештеңе пайдаланылмады.

Q: – Түзету үшін не қолдандыңыз?

ХАНЫМ: – Түзету негізінен сынақтар арқылы жүзеге асырылды. Біз ешқандай отладчик немесе GOP қолданбадық.

Q: – Жариялау функциясы орындалған слайдты қайтара аласыз ба? Бір әріпті айнымалы атаулар сізді шатастырады ма?

ХАНЫМ: - Жоқ. Олардың «тар» көріну аясы бар. Олар осы жерден басқа еш жерде қолданылмайды (осы сыныптың ішкі бөліктерін қоспағанда) және ол өте ықшам - ол тек 7 жолды алады.

Q: – Әйтеуір интуитивті емес...

ХАНЫМ: - Жоқ, жоқ, бұл нағыз код! Бұл стиль туралы емес. Бұл дәл осындай утилитарлы, өте кішкентай сынып - сыныпта тек 3 өріс бар ...

Михаил Салосин. Голанг кездесуі. Look+ қолданбасының серверінде Go пайдалану

ХАНЫМ: – Тұтастай алғанда, клиенттермен синхрондалған барлық деректер (маусымдық матчтар, ойыншылар) өзгермейді. Дөрекі айтқанда, егер біз матчты өзгерту керек басқа спорт түрін жасасақ, біз клиенттің жаңа нұсқасында бәрін ескереміз, ал клиенттің ескі нұсқаларына тыйым салынады.

Q: – Үшінші тарапқа тәуелділікті басқару пакеттері бар ма?

ХАНЫМ: – Біз go dep пайдаландық.

Q: – Баяндама тақырыбында бейне туралы бірдеңе болды, бірақ баяндамада бейне туралы ештеңе жоқ.

ХАНЫМ: – Жоқ, бейнеге қатысты тақырыпта менде ештеңе жоқ. Ол «Look+» деп аталады - бұл қолданбаның атауы.

Q: – Клиенттерге таратылады дедіңіз бе?..

ХАНЫМ: – Бейне ағынына қатыстырылған жоқпыз. Мұны толығымен Мегафон жасады. Иә, мен бұл қолданба MegaFon деп айтқан жоқпын.

ХАНЫМ: – Go – барлық деректерді жіберу үшін – есеп, матч оқиғалары, статистика туралы... Go – қолданбаның толық сервері. Пайдаланушы матчты көре алуы үшін клиент ойыншы үшін қандай сілтемені пайдалану керектігін бір жерден білуі керек. Бізде дайындалған бейнелер мен ағындарға сілтемелер бар.

Кейбір жарнамалар 🙂

Бізбен бірге болғандарыңызға рахмет. Сізге біздің мақалалар ұнайды ма? Қызықты мазмұнды көргіңіз келе ме? Тапсырыс беру немесе достарыңызға ұсыну арқылы бізге қолдау көрсетіңіз, әзірлеушілерге арналған бұлтты VPS $4.99, Сіз үшін біз ойлап тапқан бастапқы деңгейдегі серверлердің бірегей аналогы: VPS (KVM) E5-2697 v3 (6 ядросы) 10 ГБ DDR4 480 ГБ SSD 1 Гбит/с 19 доллардан немесе серверді қалай бөлісуге болатыны туралы барлық шындық? (RAID1 және RAID10, 24 ядроға дейін және 40 ГБ DDR4 дейін қол жетімді).

Dell R730xd Амстердамдағы Equinix Tier IV деректер орталығында 2 есе арзан ба? Тек осында 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6 ГГц 14C 64 ГБ DDR4 4x960 ГБ SSD 1 Гбит/с 100 теледидар 199 доллардан бастап Нидерландыда! Dell R420 - 2x E5-2430 2.2 ГГц 6C 128 ГБ DDR3 2x960 ГБ SSD 1 Гбит/с 100 ТБ - 99 доллардан бастап! туралы оқыңыз Инфрақұрылымдық корпорацияны қалай құруға болады. бір тиынға 730 еуро тұратын Dell R5xd E2650-4 v9000 серверлерін қолданатын класс?

Ақпарат көзі: www.habr.com

пікір қалдыру