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

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

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

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

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

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

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

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

Әзірлеуде не пайдаланылды?

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

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

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

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

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

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

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

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

  1. Websockets. Бірақ бізге клиенттен серверге дейінгі арналар қажет емес еді. Бізге серверден клиентке жаңартуларды жіберу ғана қажет болды, сондықтан веб-розеткалар артық болды.
  2. Server-Sent Events (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: тыңдау/хабарландыру

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Осы қолданбада жұмыс істегеннен кейін Go бағдарламасының келесі айқын артықшылықтары айқын болды.

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

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

Біз әзірлеушілерді іздейміз! Егер біреуді қызықтырса, бізге қосылыңыз.

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

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

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

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

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

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

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

Q: – Неліктен сіз өзіңіздің жеке ORM құрдыңыз?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ХАНЫМ: "Жоқ, менің тізбегімде бейнелер туралы ештеңе жоқ. Ол "Watch+" деп аталады, бұл қолданбаның аты."

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