![Search icon](https://hackernoon.imgix.net/search-new.png?w=19&h=19)
Etibarlı, yüksək əlçatan, miqyaslana bilən paylanmış sistemin qurulması xüsusi texnikalara, prinsiplərə və nümunələrə riayət etməyi tələb edir. Bu cür sistemlərin dizaynı çoxsaylı problemlərin həllini nəzərdə tutur. Ən çox yayılmış və əsas problemlərdən biri ikili yazma problemidir .
“İkili yazma problemi” paylanmış sistemlərdə, əsasən sinxron saxlanmalı olan çoxsaylı məlumat mənbələri və ya verilənlər bazası ilə işləyərkən yaranan problemdir. Bu, verilənlər bazası və ya keşlər kimi müxtəlif məlumat anbarlarına məlumat uyğunsuzluğu, ziddiyyətlər və ya performans darboğazları kimi problemlər təqdim etmədən məlumat dəyişikliklərinin ardıcıl olaraq yazılmasını təmin etmək çətinliyinə aiddir.
Mikroxidmətlərin arxitekturası və hər bir xidmət üçün nümunə verilənlər bazası sizə müstəqil yerləşdirmə və miqyaslaşdırma, təcrid olunmuş nasazlıqlar və inkişaf sürətinin potensial artımı kimi bir çox üstünlüklər gətirir. Bununla belə, əməliyyatlar çoxlu mikroservislər arasında dəyişikliklər tələb edir və sizi bu problemi həll etmək üçün etibarlı həll yolu haqqında düşünməyə məcbur edir.
Domenimizin kredit ərizələrinin qəbulunu, onların qiymətləndirilməsini və sonra müştərilərə bildiriş xəbərdarlıqlarının göndərilməsini əhatə etdiyi ssenarini nəzərdən keçirək.
Vahid məsuliyyət prinsipi, Konvey qanunu və domenə əsaslanan dizayn yanaşması ruhunda, bir neçə hadisə fırtınası seansından sonra bütün domen aydın sərhədləri, domen modelləri və hər yerdə mövcud olan dili olan müəyyən edilmiş məhdud kontekstləri olan üç alt domenə bölündü.
Birincisi, yeni kredit ərizələrini işə salmaq və tərtib etmək tapşırığıdır. İkinci sistem bu müraciətləri qiymətləndirir və verilən məlumatlar əsasında qərarlar qəbul edir. KYC/KYB, fırıldaqçılıq və kredit riski yoxlamaları da daxil olmaqla bu qiymətləndirmə prosesi çox vaxt apara bilər və eyni vaxtda minlərlə müraciəti idarə etmək qabiliyyətini tələb edə bilər. Nəticə etibarilə, bu funksionallıq müstəqil miqyasa imkan verən öz verilənlər bazası olan xüsusi mikroservisə həvalə edilmişdir.
Bundan əlavə, bu alt sistemlər hər birinin öz buraxılış dövrləri, xidmət səviyyəsi razılaşmaları (SLA) və genişlənmə tələbləri olan iki fərqli komanda tərəfindən idarə olunur.
Nəhayət , müştərilərə xəbərdarlıq göndərmək üçün xüsusi bildiriş xidməti mövcuddur.
Burada sistemin əsas istifadə halının dəqiq təsviri verilmişdir:
Bu, ilk baxışdan olduqca sadə və primitiv sistemdir, lakin gəlin Kredit müraciəti xidmətinin kredit ərizəsi göndərmə əmrini necə işlədiyinə nəzər salaq.
Xidmətin qarşılıqlı əlaqəsi üçün iki yanaşmanı nəzərdən keçirə bilərik:
Əvvəlcə Yerli Təhvil ver-Sonra Nəşr et: Bu yanaşmada xidmət yerli məlumat bazasını yeniləyir (təhsil edir) və sonra hadisə və ya mesajı digər xidmətlərə dərc edir.
Əvvəlcə dərc et, sonra yerli icra et: Əksinə, bu üsul yerli verilənlər bazasına dəyişikliklər etməzdən əvvəl hadisə və ya mesajın dərc edilməsini nəzərdə tutur.
Hər iki metodun çatışmazlıqları var və paylanmış sistemlərdə ünsiyyət üçün yalnız qismən uğursuzluqdan qorunur.
Bu, birinci yanaşmanın tətbiqi ardıcıllığı diaqramıdır.
Bu ssenaridə Kredit Müraciət Xidməti əvvəlcə əməliyyatı həyata keçirən, sonra isə başqa sistemə bildiriş göndərməyə cəhd etdiyi İlk Yerli Təhvil ver-Sonra Nəşr et yanaşmasından istifadə edir. Bununla belə, məsələn, şəbəkə problemləri varsa, Qiymətləndirmə Xidməti mövcud deyilsə və ya Kredit Müraciət Xidməti Yaddaş Kənar (OOM) xətası ilə qarşılaşarsa və qəzalar baş verərsə, bu proses uğursuzluğa həssasdır. Belə hallarda, əlavə tədbirlər həyata keçirilmədikcə, Qiymətləndirmə yeni kredit müraciəti barədə xəbərdarlıq edilmədən buraxılaraq mesaj itiriləcək.
Və ikincisi.
İlk Nəşr et-Sonra Yerli Təhvil ver ssenarisində Kredit Müraciət Xidməti daha əhəmiyyətli risklərlə üzləşir. O, Qiymətləndirmə Xidmətini yeni tətbiq haqqında məlumatlandıra bilər, lakin verilənlər bazası problemləri, yaddaş xətaları və ya kod səhvləri kimi problemlər səbəbindən bu yeniləməni yerli olaraq saxlaya bilmir. Bu yanaşma, Kredit Baxışı Xidmətinin daxil olan müraciətləri necə idarə etməsindən asılı olaraq, ciddi problemlər yarada bilən məlumatlarda əhəmiyyətli uyğunsuzluqlara səbəb ola bilər.
Buna görə də, hadisələri xarici istehlakçılara dərc etmək üçün möhkəm mexanizm təklif edən bir həll tapmalıyıq. Lakin, potensial həlləri nəzərdən keçirməzdən əvvəl, paylanmış sistemlərdə əldə edilə bilən mesajların çatdırılması zəmanətlərinin növlərini aydınlaşdırmalıyıq.
Əldə edə biləcəyimiz dörd növ zəmanət var.
Zəmanət yoxdur
Mesajın təyinat yerinə çatdırılacağına heç bir zəmanət yoxdur. “Birinci-Yerli-Öhdə-Sonra-Nəşr et” yanaşması məhz bununla bağlıdır. İstehlakçılar bir dəfə, bir neçə dəfə və ya heç vaxt mesaj ala bilərlər.
Ən çox bir dəfə çatdırılma
Ən çox bir dəfə çatdırılma mesajın təyinat yerinə ən çox 1 dəfə çatdırılması deməkdir. İlkin-Yerli-Tamamla-Sonra-Nəşr et yanaşması bir dəyərli cəhdlərin təkrar cəhd siyasəti ilə də bu şəkildə həyata keçirilə bilər.
Ən azı bir dəfə çatdırılma\İstehlakçılar hər mesajı qəbul edəcək və emal edəcəklər, lakin eyni mesajı bir dəfədən çox qəbul edə bilərlər.
Tam bir dəfə çatdırılma\Tam bir dəfə çatdırılma o deməkdir ki, istehlakçı mesajı bir dəfə effektiv şəkildə alacaq.
Texniki olaraq, Kafka əməliyyatları və istehsalçı və istehlakçının xüsusi idempotent həyata keçirilməsi ilə nail olmaq mümkündür.
Əksər hallarda "ən azı bir dəfə" çatdırılma zəmanətləri mesajların ən azı bir dəfə çatdırılmasını təmin etməklə bir çox problemi həll edir, lakin istehlakçılar iradəsiz olmalıdırlar. Bununla belə, qaçılmaz şəbəkə nasazlıqlarını nəzərə alaraq, istehsalçının zəmanətlərindən asılı olmayaraq, dublikat mesajları emal etməmək üçün bütün istehlakçı məntiqi idempotent olmalıdır. Buna görə də, bu tələb reallığı əks etdirdiyi qədər çatışmazlıq deyil.
Bu problemin öz üstünlükləri və mənfi cəhətləri olan bir çox həlli var.
Vikipediyaya görə, İki Mərhələli Öhdəlik (2PC) paylanmış əməliyyatların ardıcıllığını və etibarlılığını təmin etmək üçün kompüter elmləri və verilənlər bazası idarəetmə sistemlərində istifadə olunan paylanmış əməliyyat protokoludur. O, birdən çox resursun (məsələn, verilənlər bazası) bir əməliyyatda iştirak etməli olduğu vəziyyətlər üçün nəzərdə tutulmuşdur və o, ya onların hamısının əməliyyatı həyata keçirməsini, ya da hamısının əməliyyatı dayandırmasını təmin edir və bununla da məlumatların ardıcıllığını qoruyur. Bu, bizə lazım olan kimi səslənir, lakin İki Fazalı Təhlükəsizliyin bir sıra çatışmazlıqları var:
Mikroservis arxitekturası üçün ən aydın həll nümunə (və ya hətta bəzən anti-naxış) - paylaşılan verilənlər bazası tətbiq etməkdir. Fərqli verilənlər bazalarında birdən çox cədvəl üzrə əməliyyat ardıcıllığına ehtiyacınız varsa, bu yanaşma çox intuitivdir, sadəcə bu mikroservislər üçün bir paylaşılan verilənlər bazasından istifadə edin.
Bu yanaşmanın çatışmazlıqları arasında vahid uğursuzluq nöqtəsinin tətbiqi, müstəqil verilənlər bazası miqyasının qarşısının alınması və xüsusi tələblər və istifadə halları üçün ən uyğun olan müxtəlif verilənlər bazası həllərindən istifadə imkanının məhdudlaşdırılması daxildir. Bundan əlavə, paylanmış əməliyyatın belə bir formasını dəstəkləmək üçün mikroxidmətlərin kod bazalarına dəyişikliklər etmək lazımdır.
' Transsional poçt qutusu ', hətta etibarsız mesajlaşma sistemləri qarşısında belə etibarlı mesajın yayılmasını təmin etmək üçün paylanmış sistemlərdə istifadə edilən dizayn nümunəsidir. Bu, hadisələrin əməliyyatın özü ilə eyni əməliyyat daxilində təyin olunmuş "Gidənlər qutusu hadisələri" cədvəlində saxlanmasını nəzərdə tutur. Bu yanaşma relational verilənlər bazalarının ACID xüsusiyyətləri ilə yaxşı uyğunlaşır. Əksinə, bir çox No-SQL verilənlər bazası ACID xassələrini tam dəstəkləmir, bunun əvəzinə CAP teoreminin və BASE fəlsəfəsinin prinsiplərinə üstünlük verir, hansı ki, mövcudluğu və son ardıcıllığı ciddi ardıcıllıqdan üstün tutur.
Tranzaksiya qutusu ən azı bir dəfə zəmanət verir və bir neçə yanaşma ilə həyata keçirilə bilər:
Tranzaksiya jurnalının saxlanması
Səsvermə naşiri
Transaction log tailing yanaşması CDC (Change Data Capture) kimi verilənlər bazası üçün xüsusi həllərdən istifadə etməyi nəzərdə tutur. Bu yanaşmanın əsas çatışmazlıqları aşağıdakılardır:
Verilənlər bazası üçün xüsusi həllər
CDC tətbiqlərinin xüsusiyyətlərinə görə artan gecikmə
Başqa bir üsul, gedən qutu cədvəlini sorğulayaraq, gedən qutunun yüklənməsini asanlaşdıran Sorğu Yayımçısıdır . Bu yanaşmanın əsas çatışmazlığı daha yüksək xərclərə səbəb ola bilən verilənlər bazası yükünün artması potensialıdır. Bundan əlavə, bütün No-SQL verilənlər bazaları xüsusi sənəd seqmentləri üçün səmərəli sorğuları dəstəkləmir. Beləliklə, bütün sənədlərin çıxarılması performansın aşağı düşməsinə səbəb ola bilər.
Bunun necə işlədiyini izah edən kiçik bir ardıcıllıq diaqramıdır.
Transaction Outbox modelinin əsas problemi onun verilənlər bazası ACID xüsusiyyətlərindən asılılığındadır. Bu, tipik OLTP verilənlər bazalarında sadə ola bilər, lakin NoSQL sahəsində problemlər yaradır. Bunu həll etmək üçün potensial həll, sorğunun işlənməsinin başlanmasından dərhal sonra əlavə jurnalından (məsələn, Kafka) istifadə etməkdir.
"Kredit ərizəsini təqdim et" əmrini birbaşa emal etmək əvəzinə, biz onu dərhal daxili Kafka mövzusuna göndəririk və sonra müştəriyə "qəbul edilmiş" nəticəni qaytarırıq. Bununla belə, komandanın hələ də işlənməsinə ehtiyac olduğu ehtimalı yüksək olduğundan, nəticə barədə müştəriyə dərhal məlumat verə bilmərik. Bu son ardıcıllığı idarə etmək üçün biz uzun sorğu, müştərinin təşəbbüsü ilə sorğu, optimist UI yeniləmələri və ya bildirişlər üçün WebSockets və ya Server tərəfindən Göndərilən Hadisələrdən istifadə kimi üsullardan istifadə edə bilərik. Ancaq bu, tamamilə fərqli bir mövzudur, ona görə də ilkin mövzumuza qayıdaq.
Mesajı daxili Kafka mövzusunda göndərdik. Kredit Müraciət Xidməti daha sonra bu mesajı istehlak edir - müştəridən aldığı eyni əmri - və emal etməyə başlayır. Birincisi, bəzi iş məntiqini yerinə yetirir; yalnız bu məntiq uğurla icra edildikdən və nəticələr davam etdirildikdən sonra o, ictimai Kafka mövzusunda yeni mesajlar dərc edir.
Gəlin bir az psevdokoda nəzər salaq.
public async Task HandleAsync(SubmitLoanApplicationCommand command, ...) { //First, process business logic var loanApplication = await _loanApplicationService.HandleCommandAsync(command, ...); //Then, send new events to public Kafka topic producer.Send(new LoanApplicationSubmittedEvent(loanApplication.Id)); //Then, commit offset consumer.Commit(); }
Biznes məntiqinin işlənməsi uğursuz olarsa nə etməli? Narahat olmayın, ofset hələ həyata keçirilmədiyi üçün mesaj yenidən yoxlanılacaq.
Bəs Kafkaya yeni hadisələr göndərmək uğursuz olarsa? Narahat olmayın, biznes məntiqi idempotent olduğundan, o, dublikat kredit ərizəsi yaratmayacaq. Bunun əvəzinə o, ictimai Kafka mövzusuna mesajları yenidən göndərməyə çalışacaq.
Kafkaya mesajlar göndərilsə, lakin ofset öhdəliyi uğursuz olarsa nə etməli? Narahat olmayın, biznes məntiqi qeyri-müəyyən olduğundan, o, dublikat kredit ərizəsi yaratmayacaq. Bunun əvəzinə o, ictimai Kafka mövzusuna mesajlar göndərəcək və bu dəfə ofset öhdəliyinin uğur qazanacağına ümid edəcək.
Bu yanaşmanın əsas çatışmazlıqlarına yeni proqramlaşdırma üslubu ilə bağlı əlavə mürəkkəblik, son ardıcıllıq (çünki müştəri nəticəni dərhal bilməyəcək) və bütün biznes məntiqinin idempotent olması tələbi daxildir.
Hadisə mənbəyi nədir və onu burada necə tətbiq etmək olar? Hadisə qaynağı, bir sıra dəyişilməz hadisələr kimi verilənlərindəki bütün dəyişiklikləri ələ keçirməklə sistemin vəziyyətini modelləşdirmək üçün istifadə edilən proqram memarlıq nümunəsidir. Bu hadisələr faktları və ya dövlət keçidlərini təmsil edir və sistemin hazırkı vəziyyəti üçün yeganə həqiqət mənbəyi kimi xidmət edir. Beləliklə, texniki olaraq, hadisə qaynağı sistemini tətbiq etməklə, artıq EventStore-da bütün tədbirlərimiz var və bu EventStore istehlakçılar tərəfindən baş verənlər haqqında yeganə həqiqət mənbəyi kimi istifadə edilə bilər. Sifarişlə bağlı bütün dəyişiklikləri və ya narahatlıqları izləmək üçün xüsusi verilənlər bazası həllinə ehtiyac yoxdur, yeganə problem oxuyan tərəfdə oturmaqdır, çünki obyektin faktiki vəziyyətini əldə etmək üçün bütün hadisələri təkrarlamaq lazımdır.
Bu yazıda biz paylanmış sistemlərdə etibarlı mesajlaşma yaratmaq üçün bir neçə yanaşmanı nəzərdən keçirdik. Bu xüsusiyyətlərə malik sistemlər qurarkən nəzərə ala biləcəyimiz bir neçə tövsiyə var
Növbəti dəfə biz Transactional Outbox tətbiqinin daha praktik nümunəsinə baxacağıq. Bax
sən!