Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

Mixail Salosin (bundan sonra – MS): - Hamıya salam! Mənim adım Michael. Mən MC2 Software-də backend developer kimi işləyirəm və Look+ mobil tətbiqinin arxa hissəsində Go-dan istifadə etmək barədə danışacağam.

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

Burada xokkeyi sevən varmı?

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

Onda bu proqram sizin üçündür. O, Android və iOS üçündür və müxtəlif idman tədbirlərinin yayımlarını onlayn və qeydə alınmış şəkildə izləmək üçün istifadə olunur. Tətbiqdə həmçinin müxtəlif statistik məlumatlar, mətn yayımları, konfranslar, turnirlər üçün cədvəllər və azarkeşlər üçün faydalı olan digər məlumatlar var.

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

Tətbiqdə həmçinin video anları kimi bir şey var, yəni matçların ən vacib anlarını (qollar, döyüşlər, atışmalar və s.) izləyə bilərsiniz. Bütün verilişi izləmək istəmirsinizsə, yalnız ən maraqlılarına baxa bilərsiniz.

İnkişafda nədən istifadə etdiniz?

Əsas hissə Go dilində yazılmışdır. Mobil müştərilərin əlaqə saxladığı API Go-da yazılmışdır. Go-da mobil telefonlara push bildirişləri göndərmək xidməti də yazılmışdı. Biz də nə vaxtsa danışa biləcəyimiz öz ORM-mizi yazmalı olduq. Yaxşı, Go-da bəzi kiçik xidmətlər yazılmışdır: redaktorlar üçün şəkillərin ölçüsünü dəyişdirmək və yükləmək...

Biz verilənlər bazası kimi PostgreSQL-dən istifadə etdik. Redaktor interfeysi ActiveAdmin gemindən istifadə edərək Ruby on Rails-də yazılmışdır. Statistika provayderindən statistik məlumatların idxalı da Ruby-də yazılmışdır.

Sistem API testləri üçün biz Python vahid testindən istifadə etdik. Memcached API ödəniş zənglərini dayandırmaq üçün istifadə olunur, "Aşbaz" konfiqurasiyaya nəzarət etmək üçün, Zabbix daxili sistem statistikasını toplamaq və izləmək üçün istifadə olunur. Graylog2 qeydləri toplamaq üçündür, Slate müştərilər üçün API sənədləridir.

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

Protokol seçimi

Qarşılaşdığımız ilk problem: aşağıdakı məqamlara əsaslanaraq, backend və mobil müştərilər arasında qarşılıqlı əlaqə üçün protokol seçməli olduq...

  • Ən vacib tələb: müştərilər haqqında məlumatlar real vaxt rejimində yenilənməlidir. Yəni, hazırda yayıma baxan hər kəs demək olar ki, dərhal yenilikləri almalıdır.
  • İşləri sadələşdirmək üçün müştərilərlə sinxronlaşdırılan məlumatların silinmədiyini, lakin xüsusi bayraqlardan istifadə edərək gizlədildiyini güman etdik.
  • Bütün növ nadir sorğular (statistika, komanda tərkibi, komanda statistikası kimi) adi GET sorğuları ilə əldə edilir.
  • Üstəlik, sistem eyni anda 100 min istifadəçini asanlıqla dəstəkləməli idi.

Buna əsaslanaraq iki protokol variantımız var idi:

  1. Veb yuvaları. Amma bizə müştəridən serverə kanallar lazım deyildi. Bizə yalnız serverdən müştəriyə yeniləmələr göndərmək lazım idi, ona görə də veb-soket lazımsız seçimdir.
  2. Server-Göndərilmiş Hadisələr (SSE) tam olaraq ortaya çıxdı! Bu, olduqca sadədir və əsasən ehtiyacımız olan hər şeyi təmin edir.

Server tərəfindən göndərilən hadisələr

Bu şeyin necə işlədiyi haqqında bir neçə kəlmə...

O, http bağlantısının üstündə işləyir. Müştəri sorğu göndərir, server Content-Type: text/event-stream ilə cavab verir və müştəri ilə əlaqəni bağlamır, lakin əlaqəyə məlumat yazmağa davam edir:

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

Məlumat müştərilərlə razılaşdırılmış formatda göndərilə bilər. Bizim vəziyyətimizdə onu bu formada göndərdik: dəyişdirilmiş strukturun adı (şəxs, oyunçu) hadisə sahəsinə, oyunçu üçün yeni, dəyişdirilmiş sahələri olan JSON isə məlumat sahəsinə göndərildi.

İndi qarşılıqlı əlaqənin özünün necə işlədiyi barədə danışaq.

  • Müştərinin etdiyi ilk şey, xidmətlə sinxronizasiyanın sonuncu dəfə həyata keçirildiyini müəyyən etməkdir: o, yerli məlumat bazasına baxır və onun tərəfindən qeydə alınan son dəyişikliyin tarixini müəyyənləşdirir.
  • Bu tarixlə sorğu göndərir.
  • Cavab olaraq, biz ona həmin tarixdən bəri baş verən bütün yenilikləri göndəririk.
  • Bundan sonra o, canlı kanalla əlaqə qurur və bu yeniləmələrə ehtiyac duyana qədər bağlanmır:

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

Ona dəyişikliklərin siyahısını göndəririk: kimsə qol vursa, matçın hesabını dəyişirik, zədələnsə, bu da real vaxtda göndərilir. Beləliklə, müştərilər matç hadisəsi lentində ən son məlumatları dərhal alırlar. Müştəri serverin ölmədiyini, ona heç nə baş vermədiyini başa düşməsi üçün vaxtaşırı hər 15 saniyədən bir vaxt möhürü göndəririk - o, hər şeyin qaydasında olduğunu və yenidən qoşulmağa ehtiyac olmadığını bilsin.

Canlı əlaqə necə xidmət edir?

  • Hər şeydən əvvəl, buferlənmiş yeniləmələrin qəbul ediləcəyi bir kanal yaradırıq.
  • Bundan sonra yeniliklərdən xəbərdar olmaq üçün bu kanala abunə oluruq.
  • Müştəri hər şeyin qaydasında olduğunu bilsin deyə düzgün başlığı təyin etdik.
  • İlk ping göndərin. Biz sadəcə olaraq cari əlaqə vaxt damğasını qeyd edirik.
  • Bundan sonra, yeniləmə kanalı bağlanana qədər kanaldan bir döngədə oxuyuruq. Kanal vaxtaşırı ya cari vaxt damğasını, ya da artıq açıq əlaqələrə yazdığımız dəyişiklikləri qəbul edir.

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

Qarşılaşdığımız ilk problem belə oldu: müştəri ilə açılan hər bir əlaqə üçün biz hər 15 saniyədə bir dəfə işarələnən taymer yaratdıq - belə çıxır ki, əgər bir maşınla (bir API serveri ilə) 6 min bağlantımız olsaydı, 6 min taymer yaradılmışdır. Bu, maşının lazımi yükü saxlamamasına səbəb oldu. Problem bizim üçün o qədər də aydın deyildi, lakin biz bir az kömək aldıq və onu düzəltdik.

Nəticədə, indi pingimiz yeniləmənin gəldiyi eyni kanaldan gəlir.

Müvafiq olaraq, hər 15 saniyədə bir dəfə işarələyən yalnız bir taymer var.

Burada bir neçə köməkçi funksiya var - başlığın, pingin və strukturun özünün göndərilməsi. Yəni cədvəlin adı (şəxs, matç, mövsüm) və bu qeyd haqqında məlumat burada ötürülür:

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

Yeniləmələrin göndərilməsi mexanizmi

İndi dəyişikliklərin haradan gəldiyi haqqında bir az. Efirə real vaxt rejimində baxan bir neçə nəfərimiz, redaktorlarımız var. Bütün hadisələri yaradırlar: kimsə meydandan qovulub, kimsə zədələnib, bir növ əvəzedici...

CMS-dən istifadə edərək məlumatlar verilənlər bazasına daxil olur. Bundan sonra verilənlər bazası Dinlə/Bildirmə mexanizmindən istifadə edərək API serverlərinə bu barədə məlumat verir. API serverləri artıq bu məlumatı müştərilərə göndərir. Beləliklə, əslində verilənlər bazasına qoşulmuş bir neçə serverimiz var və verilənlər bazasında xüsusi yük yoxdur, çünki müştəri heç bir şəkildə verilənlər bazası ilə birbaşa əlaqə saxlamır:

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

PostgreSQL: Dinləyin/Xəbərdar edin

Postgres-də Dinlə/Xəbərdarlıq mexanizmi bəzi hadisənin dəyişdiyini - verilənlər bazasında bəzi qeydlərin yaradıldığını hadisə abunəçilərinə bildirməyə imkan verir. Bunun üçün sadə bir tətik və funksiya yazdıq:

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

Yazı daxil edərkən və ya dəyişdirərkən, cədvəlin adını və dəyişdirilmiş və ya daxil edilmiş qeydin identifikatorunu ora ötürərək data_updates kanalında bildiriş funksiyasını çağırırıq.

Müştəri ilə sinxronizasiya edilməli olan bütün cədvəllər üçün bir qeydi dəyişdirdikdən / yenilədikdən sonra aşağıdakı slaydda göstərilən funksiyanı çağıran bir tetikleyici təyin edirik.
API bu dəyişikliklərə necə abunə olur?

Fanout mexanizmi yaradılmışdır - o, müştəriyə mesajlar göndərir. Bütün müştəri kanallarını toplayır və bu kanallar vasitəsilə aldığı yeniləmələri göndərir:

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

Burada verilənlər bazasına qoşulan və kanala qulaq asmaq istədiyini bildirən standart pq kitabxanası (data_updates) əlaqənin açıq olduğunu və hər şeyin qaydasında olduğunu yoxlayır. Yerə qənaət etmək üçün səhv yoxlamasını buraxıram (yoxlamamaq təhlükəlidir).

Sonra, hər 15 saniyədən bir ping göndərəcək Ticker-i asinxron olaraq təyin edirik və abunə olduğumuz kanalı dinləməyə başlayırıq. Pinq alsaq, bu pingi dərc edirik. Bir növ giriş alsaq, bu girişi bu Fanoutun bütün abunəçiləri üçün dərc edirik.

Fan-out necə işləyir?

Rus dilində bu "parçalayıcı" kimi tərcümə olunur. Bəzi yeniləmələri almaq istəyən abunəçiləri qeydiyyatdan keçirən bir obyektimiz var. Və bu obyektə yeniləmə gələn kimi o, bu yeniləməni bütün abunəçilərinə paylayır. Kifayət qədər sadə:

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

Go-da necə həyata keçirilir:

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

Bir struktur var, Mutexlərdən istifadə edərək sinxronlaşdırılır. Fanout-un verilənlər bazası ilə əlaqə vəziyyətini saxlayan bir sahəyə malikdir, yəni hazırda dinləyir və yeniləmələri alacaq, həmçinin bütün mövcud kanalların siyahısı - xəritə, açarı kanal və forma şəklində strukturdur. dəyərlər (əsasən heç bir şəkildə istifadə edilmir).

İki üsul - Bağlı və Bağlantısız - Fanout-a bizim baza ilə əlaqəmiz olduğunu söyləməyə imkan verir, o ortaya çıxdı və baza ilə əlaqə pozuldu. İkinci halda, siz bütün müştəriləri ayırmalı və onlara artıq heç nəyə qulaq asa bilməyəcəklərini və onlarla əlaqə bağlandığı üçün yenidən qoşulduqlarını söyləməlisiniz.

Kanalı "dinləyicilərə" əlavə edən Abunə üsulu da var:

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

Müştəri əlaqəni kəsərsə, kanalı dinləyicilərdən silən Abunədən çıxma metodu, eləcə də bütün abunəçilərə mesaj göndərməyə imkan verən Yayımlama metodu var.

Sual: – Bu kanal vasitəsilə nələr ötürülür?

XANIM: – Dəyişən və ya ping ötürülən model (əslində sadəcə ədəd, tam ədəd).

XANIM: – Siz hər hansı bir şeyi göndərə, istənilən strukturu göndərə, dərc edə bilərsiniz – o, sadəcə JSON-a çevrilir və budur.

XANIM: – Biz Postgres-dən bildiriş alırıq – o, cədvəlin adını və identifikatorunu ehtiva edir. Cədvəlin adına və identifikatoruna əsasən, biz lazım olan qeydi alırıq və sonra bu strukturu nəşrə göndəririk.

İnfrastruktur

İnfrastruktur baxımından bu nə kimi görünür? Bizim 7 hardware serverimiz var: onlardan biri tamamilə verilənlər bazasına həsr olunub, digər altısı virtual maşınlarla işləyir. API-nin 6 nüsxəsi var: API ilə hər bir virtual maşın ayrıca hardware serverində işləyir - bu, etibarlılıq üçündür.

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

Əlçatanlığı yaxşılaşdırmaq üçün quraşdırılmış Keepalived ilə iki ön hissəmiz var ki, nəsə baş verərsə, bir cəbhə digərini əvəz edə bilsin. Həmçinin - CMS-in iki nüsxəsi.

Statistika idxalçısı da var. Vaxtaşırı ehtiyat nüsxələri edilən DB Slave var. Pigeon Pusher, müştərilərə təkan bildirişləri, eləcə də infrastruktur şeyləri göndərən bir proqram var: Zabbix, Graylog2 və Chef.

Əslində bu infrastruktur lazımsızdır, çünki daha az serverlə 100 minə xidmət göstərmək olar. Amma dəmir var idi - istifadə etdik (bizə dedilər ki, mümkündür - niyə olmasın).

Go-nun üstünlükləri

Bu proqram üzərində işlədikdən sonra Go-nun belə açıq üstünlükləri ortaya çıxdı.

  • Sərin http kitabxanası. Bununla siz qutudan çox şey yarada bilərsiniz.
  • Üstəlik, müştərilərə bildiriş göndərmək mexanizmini çox asanlıqla tətbiq etməyə imkan verən kanallar.
  • Gözəl şey Yarış detektoru bizə bir neçə kritik səhvi (infrastruktur quruluşunu) aradan qaldırmağa imkan verdi. Səhnə üzərində işləyən hər şey işə salınır, Race düyməsi ilə tərtib edilir; və buna uyğun olaraq, hansı potensial problemlərimiz olduğunu görmək üçün səhnələşdirmə infrastrukturuna baxa bilərik.
  • Minimalizm və dilin sadəliyi.

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

Biz tərtibatçılar axtarırıq! Kim istəyirsə buyursun.

Suallar

Tamaşaçıların sualı (bundan sonra – B): – Mənə elə gəlir ki, siz Fan-out ilə bağlı bir vacib məqamı qaçırdınız. Müştəriyə cavab göndərəndə müştəri oxumaq istəmədiyi halda blokladığını başa düşməkdə düzəmmi?

XANIM: - Yox, biz mane olmuruq. Birincisi, nginx-in arxasında bütün bunlar var, yəni yavaş müştərilərlə heç bir problem yoxdur. İkincisi, müştərinin buferi olan kanalı var - əslində biz ora yüzə qədər yeniləmə qoya bilərik... Kanala yaza bilməsək, onu silir. Kanalın bloklandığını görsək, sadəcə kanalı bağlayacağıq və bu qədər - hər hansı bir problem yaranarsa, müştəri yenidən qoşulacaq. Ona görə də, prinsipcə, burada heç bir bloklama yoxdur.

IN: – Dərhal identifikator cədvəlini deyil, Dinlə/Xəbərdarlığa qeyd göndərmək mümkün deyildimi?

XANIM: – Dinlə/Xəbərdar et göndərdiyi əvvəlcədən yükləmədə 8 min bayt limitə malikdir. Prinsipcə, əgər biz az miqdarda məlumatla məşğul olsaq, göndərmək mümkün olardı, amma mənə elə gəlir ki, bu üsul [bizim bunu etdiyimiz üsul] sadəcə olaraq daha etibarlıdır. Məhdudiyyətlər Postgresin özündədir.

IN: – Müştərilər onları maraqlandırmayan matçlar haqqında yeniləmələr alırlarmı?

XANIM: - Ümumiyyətlə, bəli. Bir qayda olaraq, paralel olaraq 2-3 matç gedir, hətta onda da olduqca nadirdir. Müştəri nəyəsə baxırsa, deməli, adətən baş verən matça baxır. Sonra müştərinin bütün bu yeniləmələrin əlavə olunduğu yerli məlumat bazası var və hətta İnternet bağlantısı olmadan müştəri yeniləmələri olan bütün keçmiş matçlara baxa bilər. Əslində, biz serverdəki verilənlər bazamızı müştərinin yerli verilənlər bazası ilə sinxronlaşdırırıq ki, o, oflayn işləyə bilsin.

IN: – Niyə öz ORM-nizi yaratdınız?

Aleksey (Look+ proqramının tərtibatçılarından biri): – O vaxt (bir il əvvəl idi) indiki ilə müqayisədə daha az ORM var idi, halbuki onların sayı kifayət qədər çoxdur. Oradakı əksər ORM-lər haqqında ən çox sevdiyim şey, onların əksəriyyətinin boş interfeyslərdə işləməsidir. Yəni, bu ORM-lərdəki üsullar hər şeyi qəbul etməyə hazırdır: struktur, struktur göstəricisi, nömrə, tamamilə əhəmiyyətsiz bir şey...

Bizim ORM məlumat modelinə əsaslanan strukturlar yaradır. Özüm. Və buna görə də bütün üsullar konkretdir, əks etdirmir və s. Onlar strukturları qəbul edir və gələn strukturlardan istifadə etməyi gözləyirlər.

IN: - Neçə nəfər iştirak etdi?

XANIM: – İlkin mərhələdə iki nəfər iştirak edirdi. İyun ayında hardasa başladıq, avqustda isə əsas hissə hazır idi (birinci variant). Sentyabr ayında buraxılış var idi.

IN: – SSE-ni təsvir etdiyiniz yerdə siz vaxt aşımından istifadə etmirsiniz. Niyə belədir?

XANIM: – Düzünü desəm, SSE hələ də html5 protokoludur: SSE standartı mənim anladığım qədər brauzerlərlə əlaqə saxlamaq üçün nəzərdə tutulub. Brauzerlərin yenidən qoşula bilməsi (və s.) üçün əlavə funksiyalara malikdir, lakin onlara ehtiyacımız yoxdur, çünki məlumatların qoşulması və qəbulu üçün istənilən məntiqi həyata keçirə bilən müştərilərimiz var idi. Biz SSE yaratmadıq, əksinə SSE-yə bənzər bir şey yaratdıq. Bu, protokolun özü deyil.
Ehtiyac yoxdu. Anladığım qədər, müştərilər əlaqə mexanizmini demək olar ki, sıfırdan həyata keçiriblər. Onlar həqiqətən əhəmiyyət vermədilər.

IN: – Əlavə olaraq hansı kommunal xidmətlərdən istifadə etmisiniz?

XANIM: – Stilin vahid olması üçün biz ən fəal şəkildə govet və qolintdən istifadə etdik, o cümlədən gofmt. Başqa heç nə istifadə olunmayıb.

IN: - Sazlamaq üçün nədən istifadə etdiniz?

XANIM: – Sazlama əsasən testlərdən istifadə etməklə həyata keçirilib. Biz heç bir sazlayıcı və ya GOP istifadə etməmişik.

IN: – Publish funksiyasının həyata keçirildiyi slaydı qaytara bilərsinizmi? Tək hərfli dəyişən adlar sizi çaşdırırmı?

XANIM: - Yox. Onların kifayət qədər "dar" görünmə dairəsi var. Onlar buradan başqa heç bir yerdə istifadə edilmir (bu sinifin daxili hissələri istisna olmaqla) və çox yığcamdır - cəmi 7 sətir çəkir.

IN: - Nədənsə hələ də intuitiv deyil...

XANIM: - Yox, yox, bu əsl koddur! Stillə bağlı deyil. Bu, elə bir utilitar, çox kiçik bir sinifdir - sinif daxilində cəmi 3 sahə...

Mixail Salosin. Golang görüşü. Look+ proqramının arxa hissəsində Go istifadə edin

XANIM: – Ümumiyyətlə, müştərilərlə sinxronlaşdırılan bütün məlumatlar (mövsüm oyunları, oyunçular) dəyişmir. Kobud desək, matçı dəyişdirməli olduğumuz başqa bir idman növü etsək, sadəcə olaraq müştərinin yeni versiyasında hər şeyi nəzərə alacağıq və müştərinin köhnə versiyaları qadağan ediləcək.

IN: – Üçüncü tərəfdən asılılıq idarəetmə paketləri varmı?

XANIM: – Go dep istifadə etdik.

IN: – Hesabatın mövzusunda video ilə bağlı nəsə var idi, amma reportajda video ilə bağlı heç nə yox idi.

XANIM: – Xeyr, video ilə bağlı mövzuda heç nə yoxdur. O, “Bax+” adlanır - proqramın adı belədir.

IN: – Dediniz ki, müştərilərə ötürülür?..

XANIM: – Videoların yayımında iştirak etməmişik. Bu, tamamilə Megafon tərəfindən edildi. Bəli, tətbiqin MegaFon olduğunu demədim.

XANIM: – Get – bütün məlumatları göndərmək üçün – hesab, matç hadisələri, statistika haqqında... Go proqram üçün bütün arxa plandır. Müştəri haradansa oyunçu üçün hansı keçiddən istifadə edəcəyini bilməlidir ki, istifadəçi matçı izləyə bilsin. Hazırlanmış videolara və axınlara keçidlərimiz var.

Bəzi reklamlar 🙂

Bizimlə qaldığınız üçün təşəkkür edirik. Məqalələrimiz xoşunuza gəlirmi? Daha maraqlı məzmun görmək istəyirsiniz? Sifariş verməklə və ya dostlarınıza tövsiyə etməklə bizə dəstək olun, developers üçün bulud VPS 4.99 dollardan, Sizin üçün bizim tərəfimizdən icad edilmiş giriş səviyyəli serverlərin unikal analoqu: VPS (KVM) E5-2697 v3 (6 nüvəli) 10GB DDR4 480GB SSD 1Gbps haqqında 19 dollardan bütün həqiqət və ya serveri necə paylaşmaq olar? (RAID1 və RAID10, 24 nüvəyə qədər və 40 GB DDR4 ilə mövcuddur).

Dell R730xd Amsterdamdakı Equinix Tier IV məlumat mərkəzində 2 dəfə ucuzdur? Yalnız burada 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV 199$-dan başlayan qiymətlərlə Hollandiyada! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - 99 dollardan! haqqında oxuyun İnfrastruktur korporasiyasını necə qurmaq olar. bir qəpik üçün 730 avro dəyərində Dell R5xd E2650-4 v9000 serverlərinin istifadəsi ilə sinif?

Mənbə: www.habr.com

Добавить комментарий