Tinder matçlarınızı və mesajlarınızı miqyasda necə çatdırır

Müəllif: Dimitar Dyankov, Mühəndis Müdiri | Trystan Johnson, Sr Proqram Mühəndisi | Kyle Bendickson, Proqram Mühəndisi | Frank Ren, Mühəndislik direktoru

Giriş

Son vaxtlara qədər, Tinder tətbiqi bunu hər iki saniyədə serverdə sorğu keçirərək həyata keçirdi. Hər iki saniyədə tətbiqini açan hər kəs yeni bir şey olub olmadığını görmək üçün bir müraciət edəcəkdi - vaxtın böyük əksəriyyəti cavabı "Xeyr, sizin üçün yeni bir şey deyil." Bu model işləyir və Tinder tətbiqetməsinin yarandığı gündən bəri yaxşı işləmişdir, ancaq növbəti addım atmağın vaxtı gəldi.

Motivasiya və məqsədlər

Səsvermə ilə əlaqədar bir çox eniş var. Mobil məlumatlar lazımsız istehlak olunur, bu qədər boş trafiklə məşğul olmaq üçün bir çox serverə ehtiyacınız var və orta hesabla aktual yeniləmələr bir saniyəlik gecikmə ilə geri qayıdır. Ancaq kifayət qədər etibarlı və proqnozlaşdırıla biləndir. Yeni bir sistem tətbiq edərkən etibarlılığı qurban vermədən, bütün bu mənfi cəhətləri yaxşılaşdırmaq istədik. Real vaxt rejimində tədarükü mövcud infrastrukturun çoxunu pozmayan bir şəkildə artırmaq istədik, amma yenə də genişləndirmək üçün bir platforma verdi. Beləliklə, Layihə Keepalive dünyaya gəldi.

Memarlıq və Texnologiya

Bir istifadəçinin hər zaman yeni bir yeniləmə (uyğunluq, mesaj və s.) Olmasına baxmayaraq, bu yeniləməyə cavabdeh olan servis xidməti Keepalive boru kəmərinə bir mesaj göndərir - biz onu bir düyün adlandırırıq. Bir çılpaqlığın çox kiçik olması nəzərdə tutulur - "Hey, bir şey yenidir!" Deyən bildiriş kimi daha çox düşünün. Müştərilər bu çılpaqlığı aldıqda, əvvəllər olduğu kimi, yeni məlumatları da alacaqlar - yalnız indi, biz yeni yeniləmələr barədə məlumat verdiyimiz üçün onlar həqiqətən bir şey əldə edəcəklərinə əminik.

Ən yaxşı bir səy olduğuna görə bunu bir dudaq adlandırırıq. Nudge server və ya şəbəkə problemləri səbəbiylə çatdırıla bilmirsə, dünyanın sonu deyil; növbəti istifadəçi yeniləməsi başqa birini göndərir. Ən pis vəziyyətdə, tətbiq yeniləmələrini aldığından əmin olmaq üçün hər halda vaxtaşırı yoxlayır. Tətbiqdə bir WebSocket olduğu üçün Nudge sisteminin işlədiyinə zəmanət vermir.

Başlamaq üçün, Gateway xidmətinə zəng gəlir. Bu, yüngül HTTP xidmətidir, Keepalive sisteminin bəzi detallarını mücərrədləşdirməyə cavabdehdir. Şlüz, sonra Nudge'nin ömrü boyu istifadə edilən Protokol Bufer mesajı qurur. Protobuflar sərt bir müqavilə və tip sistemini təyin edirlər, halbuki çox yüngül və sürətləndirmək üçün çox sürətli.

Zamanlı çatdırılma mexanizmi olaraq WebSockets’i seçdik. MQTT-yə də baxmağa vaxt sərf etdik, lakin mövcud brokerlərdən məmnun deyildim. Tələblərimiz bir ton əməliyyata mürəkkəblik əlavə etməyən çoxsaylı, açıq mənbəli bir sistem idi, bu da qapıdan kənarda bir çox brokerləri sıradan çıxardı. Mosquitto, HiveMQ və emqttd'nin buna baxmayaraq işləmələrini yoxlamaq üçün daha da nəzərdən keçirdik, lakin bunları da istisna etdik (Mosquitto, çoxlaya bilməməsi üçün HiveMQ, açıq mənbəli olmadığına görə HiveMQ və Erlanq əsaslı bir sistem tətbiq etdikləri üçün emqttd) bizim bu layihə üçün əlimiz çatmadı). MQTT ilə bağlı xoş bir şey, protokolun müştəri batareyası və bant genişliyi üçün çox yüngüldür və vasitəçi həm TCP borusunu, həm də pub / alt sistemini hamısında birləşdirir. Bunun əvəzinə bu məsuliyyətləri bir-birindən ayırmağı seçdik - cihazla WebSocket bağlantısını qorumaq üçün Go xidmətini işlətmək və pub / sub marşrutlaşdırma üçün NATS istifadə. Hər bir istifadəçi xidmətimizlə bir WebSocket qurur, sonra həmin istifadəçi üçün NATS-ə abunə olur. Beləliklə, hər bir WebSocket prosesi on minlərlə istifadəçinin abunəçilərini NATS-lə bir əlaqə üzərində multipleksasiya edir.

NATS çoxluğu aktiv abunəçilər siyahısının aparılmasına cavabdehdir. Hər bir istifadəçinin abunə mövzusu olaraq istifadə etdiyimiz unikal identifikator var. Bu yolla, bir istifadəçinin olduğu hər bir onlayn cihaz eyni mövzunu dinləyir - və bütün cihazlara eyni vaxtda bildiriş göndərilə bilər.

Nəticələr

Ən maraqlı nəticələrdən biri çatdırılmada sürətlənmə oldu. Əvvəlki sistemlə orta çatdırılma gecikməsi 1,2 saniyəyə bərabər idi - WebSocket çılpaqlığı ilə bunu təxminən 300ms-a endirdik - 4x inkişaf.

Yeniləmə xidmətimizdəki trafik - matçların və mesajların səsvermə yolu ilə qaytarılmasına cavabdeh olan sistem də nəzərəçarpacaq dərəcədə azalıb, bu da tələb olunan mənbələri azaltmağa imkan verir.

Nəhayət, tipik göstəriciləri səmərəli şəkildə həyata keçirməyə imkan verən digər zamanlı xüsusiyyətlərə qapı açır.

Öyrənilmiş dərslər

Əlbətdə ki, bəzi yayma problemləri ilə də qarşılaşdıq. Yol boyunca Kubernetes resurslarını tənzimləmək haqqında çox şey öyrəndik. Əvvəlcə düşünmədiyimiz bir şey, WebSockets-in bir serveri dövlət halına gətirməsidir, buna görə də köhnə zibilləri tez bir zamanda çıxara bilmərik - təkrar fırtınanın qarşısını almaq üçün təbii olaraq dövr etmələrinə imkan verən yavaş, zərif bir yayma prosesimiz var.

Bağlı istifadəçilərin müəyyən bir miqyasında yalnız WebSocket-də deyil, gecikmənin kəskin artımlarını müşahidə etməyə başladıq; bu digər bütün podlara da təsir etdi! Bir həftə və ya daha çox müxtəlif ölçülü yerləşdirmədən, kodu düzəltməyə çalışan və zəifliyi axtaran çox sayda ölçü əlavə etdikdən sonra nəhayət günahkarımızı tapdıq: fiziki ana bağlantısı izləmə məhdudiyyətlərini vura bildik. Bu, ev sahibi bütün qovluqları gecikmə müddətini artıran şəbəkə trafikinə müraciətləri növbələşdirməyə məcbur edəcəkdir. Sürətli həll daha çox WebSocket pods əlavə edərək təsirini yaymaq üçün onları müxtəlif aparıcılara məcbur etdi. Ancaq qısa müddət sonra kök məsələsini ortaya çıxardıq - dmesg qeydlərini yoxladıqda çox sayda “ip_conntrack: masa dolu; paket düşmə. " Həqiqi həll daha yüksək bir əlaqə sayını təmin etmək üçün ip_conntrack_max parametrini artırmaq idi.

Biz də gözləmədiyimiz Go HTTP müştəri ətrafında bir neçə məsələyə rast gəldik - Dialer'i daha çox əlaqəni açmaq üçün tənzimləməliyik və daima cavab orqanını istəmədiyimiz halda tam oxuduğumuzu təmin etməliyik.

NATS də bəzi nöqsanları yüksək miqyasda göstərməyə başladı. Hər iki həftədə bir dəfə, çoxluq içərisində olan iki ana bir-birlərini Yavaş İstehlakçılar olaraq bildirirlər - əsasən, bir-birlərindən əl çəkə bilmədilər (mövcud imkanlardan çox olmasına baxmayaraq). Şəbəkə buferi sahibi arasında istehlak edilməsinə əlavə vaxt ayırmaq üçün write_deadline-ı artırdıq.

Növbəti addımlar

İndi bu sistemimiz mövcud olduğundan, bunun üzərində genişlənməyə davam etmək istərdik. Gələcək iterasiya bir düyün anlayışını tamamilə ləğv edə bilər və birbaşa məlumat ötürə bilər - gecikmə və yerüstülüyü daha da azaldır. Bu, yazaraq göstərici kimi digər real vaxt imkanlarını da açır.

Links

Android üçün Əqrəb: https://medium.com/tinder-engineering/taming-websocket-with-scarlet-f01125427677

NATS: https://nats.io/