Кафкадағы асинхронды API көмегімен Қайтару құралы қызметін әзірлеу тәжірибесі

Оңтайландырылған процесі және ондаған өзара байланысты қызметтері бар Lamoda сияқты ірі компанияны өз көзқарасын айтарлықтай өзгертуге не мәжбүрлей алады? Мотивация мүлдем басқаша болуы мүмкін: заң шығарудан бастап барлық бағдарламашыларға тән эксперименттерге ұмтылуға дейін.

Бірақ бұл сіз қосымша артықшылықтарға сене алмайсыз дегенді білдірмейді. Сергей Зайка сізге Кафкада оқиғаларға негізделген API енгізсеңіз, нақты не ұтып алатыныңызды айтып береді (аз). Сондай-ақ үлкен кадрлар мен қызықты жаңалықтар туралы сөз болады - эксперимент оларсыз болмайды.

Кафкадағы асинхронды API көмегімен Қайтару құралы қызметін әзірлеу тәжірибесі

Жауапкершіліктен бас тарту: Бұл мақала Сергей 2018 жылдың қарашасында HighLoad++ бағдарламасында өткізген кездесу материалдарына негізделген. Ламоданың Кафкамен жұмыс істеу тәжірибесі тыңдаушыларды кестедегі басқа есептерден кем емес қызықтырды. Біздің ойымызша, бұл сіз әрқашан пікірлес адамдарды таба алатындығыңызды және қажет екендігіңіздің тамаша мысалы, ал HighLoad++ ұйымдастырушылары бұған қолайлы атмосфера құруға тырысады.

Процесс туралы

Lamoda - өзінің байланыс орталығы, жеткізу қызметі (және көптеген филиалдары), фотостудиясы, үлкен қоймасы бар үлкен электрондық коммерция платформасы және мұның барлығы жеке бағдарламалық жасақтамада жұмыс істейді. Ондаған төлем әдістері бар, b2b серіктестері осы қызметтердің кейбірін немесе барлығын пайдалана алады және өз өнімдері туралы соңғы ақпаратты білгісі келеді. Сонымен қатар, Lamoda Ресей Федерациясынан басқа үш елде жұмыс істейді және ол жерде бәрі басқаша. Жалпы алғанда, жаңа тапсырысты конфигурациялаудың жүзден астам жолы бар, олар өзінше өңделуі керек. Мұның бәрі кейде айқын емес тәсілдермен байланысатын ондаған қызметтердің көмегімен жұмыс істейді. Сондай-ақ, негізгі жауапкершілігі тапсырыс мәртебесі болып табылатын орталық жүйе бар. Біз оны БОБ деп атаймыз, мен онымен жұмыс істеймін.

Оқиғаларға негізделген API бар қайтару құралы

Оқиғаларға негізделген сөз өте күрделі; сәл әрі қарай біз бұл нені білдіретінін толығырақ анықтаймыз. Мен Кафкадағы оқиғаларға негізделген API тәсілін қолданып көруді шешкен контекстен бастаймын.

Кафкадағы асинхронды API көмегімен Қайтару құралы қызметін әзірлеу тәжірибесі

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

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

Кафкадағы асинхронды API көмегімен Қайтару құралы қызметін әзірлеу тәжірибесі

Біздің мотивация:

  1. Заң ФЗ-54 - қысқаша айтқанда, заң салық органына әрбір ақша операциясы туралы есеп беруді талап етеді, ол қайтару немесе түбіртек болсын, бірнеше минуттық өте қысқа SLA ішінде. Біз электронды коммерция компаниясы ретінде көптеген операцияларды орындаймыз. Техникалық тұрғыдан бұл жаңа жауапкершілікті (демек, жаңа қызмет) және барлық тартылған жүйелердегі жақсартуларды білдіреді.
  2. BOB бөлінді BOB-ті көптеген негізгі емес жауапкершіліктерден босату және оның жалпы күрделілігін азайту жөніндегі компанияның ішкі жобасы.

Кафкадағы асинхронды API көмегімен Қайтару құралы қызметін әзірлеу тәжірибесі

Бұл диаграмма негізгі Lamoda жүйелерін көрсетеді. Қазір олардың көпшілігі көбірек кішірейіп бара жатқан монолиттің айналасындағы 5-10 микросервистерден тұратын шоқжұлдыз. Олар баяу өсуде, бірақ біз оларды кішірейтуге тырысамыз, өйткені ортасында таңдалған фрагментті орналастыру қорқынышты - біз оның құлауына жол бере алмаймыз. Біз барлық алмасуларды (көрсеткілерді) сақтап қоюға мәжбүрміз және олардың кез келгені қолжетімсіз болып шығуы мүмкін екенін ескереміз.

BOB-де көптеген биржалар бар: төлем жүйелері, жеткізу жүйелері, хабарландыру жүйелері және т.б.

Техникалық тұрғыдан BOB дегеніміз:

  • ~150к код жолдары + ~100к сынақ жолдары;
  • php7.2 + Zend 1 және Symfony компоненттері 3;
  • >100 API & ~50 шығыс интеграциясы;
  • Өз бизнес логикасы бар 4 ел.

BOB-ті орналастыру қымбат және ауыр, ол шешетін код пен мәселелердің көлемі ешкім мұның бәрін басына сала алмайды. Жалпы, оны жеңілдетудің көптеген себептері бар.

Қайтару процесі

Бастапқыда процеске екі жүйе қатысады: BOB және Төлем. Енді тағы екеуі пайда болады:

  • Фискализациялау және сыртқы қызметтермен байланыс мәселелерін шешетін фискализация қызметі.
  • Қаражатты қайтару құралы, ол тек қана BOB-ті арттырмау үшін жаңа алмасуларды қамтиды.

Енді процесс келесідей көрінеді:

Кафкадағы асинхронды API көмегімен Қайтару құралы қызметін әзірлеу тәжірибесі

  1. BOB ақшаны қайтару туралы сұрау алады.
  2. BOB осы қайтару құралы туралы айтады.
  3. Қайтару құралы Төлемге: «Ақшаны қайтарыңыз» дейді.
  4. Төлем ақшаны қайтарады.
  5. Қайтару құралы және BOB күйлерді бір-бірімен синхрондайды, өйткені қазір екеуіне де қажет. Біз қайтару құралына толығымен ауысуға әлі дайын емеспіз, өйткені BOB-де UI, бухгалтерлік есептерге арналған есептер және жалпы оңай тасымалданбайтын деректер көп. Сіз екі орындыққа отыруыңыз керек.
  6. Фискализация туралы өтініш жойылады.

Нәтижесінде біз Кафкада оқиға автобусының бір түрін жасадық - оқиға-автобус, онда барлығы басталды. Ура, енді бізде бір сәтсіздік (сарказм) бар.

Кафкадағы асинхронды API көмегімен Қайтару құралы қызметін әзірлеу тәжірибесі

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

Оқиғаларға негізделген API дегеніміз не

Бұл сұраққа жақсы жауап Мартин Фаулердің есебінде (GOTO 2017) «Оқиғаға негізделген архитектураның көп мағыналары».

Біз не істедік қысқаша:

  1. арқылы барлық асинхронды алмасуларды аяқтаңыз оқиғаларды сақтау. Әрбір мүдделі тұтынушыны желі арқылы күйдің өзгеруі туралы хабардар етудің орнына, біз орталықтандырылған жадқа күйдің өзгеруі туралы оқиға жазамыз, ал тақырыпқа қызығушылық танытқан тұтынушылар сол жерден пайда болатынның бәрін оқиды.
  2. Бұл жағдайда оқиға хабарлама болып табылады (хабарландырулар) бір жерде бір нәрсе өзгерді. Мысалы, тапсырыс күйі өзгерді. Хабарландыруға қосылмаған күйдің өзгеруімен бірге жүретін кейбір деректерге қызығушылық танытқан тұтынушы оның күйін өзі біле алады.
  3. Максималды опция - толыққанды оқиға көзі, мемлекеттік трансферт, қай жағдайда өңдеуге қажетті барлық ақпаратты қамтиды: ол қайдан келді және қандай күйге өтті, деректер нақты қалай өзгерді және т.б.. Жалғыз сұрақ - сіз сақтауға болатын ақпараттың мүмкіндігі мен көлемі.

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

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

Асинхронды алмасу

Асинхронды алмасулар үшін РНР бөлімі әдетте RabbitMQ пайдаланады. Біз сұрау үшін деректерді жинадық, оны кезекке қойдық, сол қызметтің тұтынушысы оны оқып, жіберді (немесе жібермеді). API өзі үшін Lamoda Swagger қолданбасын белсенді пайдаланады. Біз API құрастырамыз, оны Swagger бағдарламасында сипаттаймыз және клиент пен сервер кодын жасаймыз. Біз сондай-ақ сәл жақсартылған JSON RPC 2.0 қолданамыз.

Кейбір жерлерде ESB автобустары пайдаланылады, кейбіреулері activeMQ-де тұрады, бірақ, жалпы, RabbitMQ - стандартты.

Асинхронды алмасу TO BE

Оқиғалар автобусы арқылы алмасуды жобалау кезінде ұқсастықты байқауға болады. Оқиға құрылымының сипаттамалары арқылы біз болашақ деректер алмасуды осылай сипаттаймыз. Yaml пішімі, біз кодты генерациялауды өзіміз жасауымыз керек еді, генератор спецификацияға сәйкес DTO жасайды және клиенттер мен серверлерді олармен жұмыс істеуге үйретеді. Ұрпақ екі тілге ауысады - голанг және php. Бұл кітапханаларды дәйекті сақтауға көмектеседі. Генератор голанг тілінде жазылған, сондықтан ол гоги атауын алды.

Кафкадағы оқиға көзін алу әдеттегі нәрсе. Kafka Confluent негізгі кәсіпорын нұсқасынан шешім бар, бар накади, біздің домен ағаларымыз Zalando шешімі. Біздің ваниль Кафкадан бастауға мотивация - бұл шешімді біз оны барлық жерде қолданамыз ба, жоқ па, соны шешкенге дейін еркін қалдыруды білдіреді, сонымен қатар маневр мен жақсартулар үшін өзімізге орын қалдырамыз: біз өзімізге қолдау көрсеткіміз келеді. JSON RPC 2.0, екі тілге арналған генераторлар және тағы не көрейік.

Тіпті осындай бақытты жағдайда, шамамен ұқсас шешім қабылдаған Заландо бизнесі болған кезде де, біз оны тиімді пайдалана алмаймыз.

Іске қосу кезіндегі архитектуралық үлгі келесідей: біз тікелей Кафкадан оқимыз, бірақ тек оқиғалар автобусы арқылы жазамыз. Кафкада оқуға дайын көп нәрсе бар: брокерлер, балансирлер және ол көлденең масштабтауға азды-көпті дайын, мен мұны сақтағым келді. Біз жазуды бір шлюз aka Events-автобус арқылы аяқтағымыз келді, сондықтан міне.

Оқиғалар - автобус

Немесе оқиға автобусы. Бұл жай ғана азаматтығы жоқ http шлюзі, ол бірнеше маңызды рөлдерді атқарады:

  • Валидация жасау — біз оқиғалардың біздің техникалық талаптарға сәйкестігін тексереміз.
  • Оқиға шебері жүйесі, яғни бұл қандай оқиғалар қандай құрылымдармен жарамды болып саналады деген сұраққа жауап беретін компаниядағы негізгі және жалғыз жүйе. Тексеру жай ғана мазмұнды қатаң түрде көрсету үшін деректер түрлері мен сандарды қамтиды.
  • Хэш функциясы бөлу үшін - Кафка хабарының құрылымы кілт-мән болып табылады және кілт хэшінің көмегімен оны қайда қою керектігі есептеледі.

неге

Біз процесі жеңілдетілген ірі компанияда жұмыс істейміз. Неліктен бірдеңені өзгерту керек? Бұл эксперимент, және біз бірнеше артықшылықтар аламыз деп күтеміз.

1:n+1 алмасу (бірден көпке)

Кафка жаңа тұтынушыларды API интерфейсіне қосуды жеңілдетеді.

Сізде бірден бірнеше жүйеде (және кейбір жаңаларында) жаңартылған каталог бар делік. Бұрын біз set-API іске асыратын буманы ойлап таптық, ал негізгі жүйе тұтынушы мекенжайлары туралы хабардар болды. Енді мастер-жүйе тақырыпқа жаңартуларды жібереді және оны қызықтыратындардың барлығы оқиды. Жаңа жүйе пайда болды - біз оған тақырыпқа жазылдық. Иә, сонымен қатар топтама, бірақ қарапайым.

BOB бөлігі болып табылатын қайтару құралы жағдайында оларды Кафка арқылы синхрондауды сақтау ыңғайлы. Төлем ақшаның қайтарылғанын айтады: БОБ, RT бұл туралы біліп, статустарын өзгертті, Фискализация қызметі бұл туралы біліп, чек берді.

Кафкадағы асинхронды API көмегімен Қайтару құралы қызметін әзірлеу тәжірибесі

Клиентті оның тапсырысы/қайтарулары туралы жаңалықтар туралы хабардар ететін бірыңғай хабарландыру қызметін құру жоспарымызда бар. Енді бұл жауапкершілік жүйелер арасында таратылады. Хабарландырулар қызметіне Кафкадан тиісті ақпаратты алуға және оған жауап беруге үйрету (және басқа жүйелерде бұл хабарландыруларды өшіру) жеткілікті болады. Жаңа тікелей алмасулар қажет емес.

Деректерге негізделген

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

Репликация журналы

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

Репликация журналының сақтау мерзімі осы тақырыпқа жазудың қарқындылығына байланысты; Кафка сақтау уақыты мен деректер көлеміне шектеулерді икемді орнатуға мүмкіндік береді. Қарқынды тақырыптар үшін барлық тұтынушылардың ақпаратты жоғалып кетпес бұрын, тіпті қысқа мерзімді жұмыс істемеу жағдайында да оқуға уақыты болуы маңызды. Әдетте деректерді сақтауға болады күн бірліктері, бұл қолдау үшін жеткілікті.

Кафкадағы асинхронды API көмегімен Қайтару құралы қызметін әзірлеу тәжірибесі

Әрі қарай, Кафкамен таныс емес адамдар үшін құжаттаманы аздап қайталау (сурет те құжаттамадан алынған)

AMQP-де кезек бар: біз тұтынушы үшін кезекке хабарлама жазамыз. Әдетте, бір кезек бірдей бизнес логикасы бар бір жүйемен өңделеді. Бірнеше жүйені хабардар ету қажет болса, қолданбаны бірнеше кезекке жазуды үйретуге немесе олардың өзін клондайтын fanout механизмімен алмасуды конфигурациялауға болады.

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

Тиісінше, әртүрлі логиканы жүзеге асыруға болады. Мысалы, бізде әртүрлі елдер үшін 4 инстанцияда BOB бар - Lamoda Ресейде, Қазақстанда, Украинада, Беларусьте. Олар бөлек орналастырылғандықтан, олардың сәл өзгеше конфигурациялары және өздерінің бизнес логикасы бар. Хабарламада қай елге қатысты екенін көрсетеміз. Әрбір елдегі әрбір BOB тұтынушысы басқа groupId арқылы оқиды және хабар оларға қатысты болмаса, олар оны өткізіп жібереді, яғни. дереу +1 офсетті жасайды. Егер сол тақырыпты біздің Төлем қызметі оқыса, ол мұны бөлек топпен жасайды, сондықтан офсеттер қиылыспайды.

Оқиғаға қойылатын талаптар:

  • Деректер толықтығы. Мен оқиғаның өңделуі үшін жеткілікті деректер болуын қалаймын.

  • Тұтастық Біз Events-bus бағдарламасына оқиғаның дәйекті екенін және оны өңдей алатынын растауды тапсырамыз.
  • Тапсырыс маңызды. Қайтарған жағдайда тарихпен жұмыс істеуге мәжбүрміз. Хабарландырулармен тапсырыс маңызды емес, егер олар біртекті хабарландырулар болса, қандай тапсырыс бірінші келгеніне қарамастан электрондық пошта бірдей болады. Ақшаны қайтару жағдайында нақты процесс бар; егер тапсырысты өзгертсек, ерекшеліктер туындайды, қайтару жасалмайды немесе өңделмейді - біз басқа мәртебеге ие боламыз.
  • Жүйелілік. Бізде дүкен бар, енді API орнына оқиғалар жасаймыз. Бізге қызметтерімізге жаңа оқиғалар мен бар өзгерістер туралы ақпаратты жылдам және арзан жіберудің жолы қажет. Бұған жеке git репозиторийінде және код генераторларында ортақ спецификация арқылы қол жеткізіледі. Сондықтан әртүрлі қызметтердегі клиенттер мен серверлер келісілген.

Ламодадағы Кафка

Бізде үш Кафка қондырғысы бар:

  1. Журналдар;
  2. ҒЗТКЖ;
  3. Оқиғалар - автобус.

Бүгін біз тек соңғы нүкте туралы айтып отырмыз. Оқиғалар автобусында бізде өте үлкен қондырғылар жоқ - 3 брокер (сервер) және тек 27 тақырып. Әдетте, бір тақырып бір процесс. Бірақ бұл нәзік мәселе, біз оған қазір тоқталамыз.

Кафкадағы асинхронды API көмегімен Қайтару құралы қызметін әзірлеу тәжірибесі

Жоғарыда rps графигі берілген. Қайтару процесі көгілдір сызықпен белгіленген (иә, X осіндегі), ал қызғылт сызық мазмұнды жаңарту процесі болып табылады.

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

Қызғылт шыңдар - бұл өнімнің жаңартулары, яғни өнімдердегі өзгерістер. Жігіттер суретке түсіп, суретке түсіп, кейін тағы да көрініп тұр! — оқиғалар пакеті жүктелді.

Lamoda Events қолдану жағдайлары

Біз құрастырылған архитектураны келесі операциялар үшін пайдаланамыз:

  • Қайтару күйін қадағалау: әрекетке шақыру және барлық тартылған жүйелерден күйді бақылау. Төлем, күйлер, фискализация, хабарламалар. Мұнда біз тәсілді сынап көрдік, құралдар жасадық, барлық қателерді жинадық, құжаттама жазды және әріптестерімізге оны қалай пайдалану керектігін айттық.
  • Өнім карталарын жаңарту: конфигурация, метадеректер, сипаттамалар. Бір жүйе оқиды (көрсетеді) және бірнеше жазады.
  • Электрондық пошта, push және sms: тапсырыс жиналды, тапсырыс келді, қайтару қабылданды, т.б., олар көп.
  • Қорды, қойманы жаңарту — заттардың сандық жаңаруы, жай сандар: қоймаға келу, қайтару. Тауарларды брондаумен байланысты барлық жүйелер ең өзекті деректермен жұмыс істеуі қажет. Қазіргі уақытта қорларды жаңарту жүйесі өте күрделі, Кафка оны жеңілдетеді.
  • Деректерді талдау (ҒЗТКЖ бөлімі), ML құралдары, аналитика, статистика. Біз ақпараттың ашық болуын қалаймыз - Кафка бұл үшін өте қолайлы.

Енді соңғы алты айда болған үлкен соққылар мен қызықты жаңалықтар туралы қызықты бөлім.

Дизайн мәселелері

Біз жаңа нәрсе жасағымыз келеді делік - мысалы, бүкіл жеткізу процесін Кафкаға ауыстырыңыз. Қазір процестің бір бөлігі BOB жүйесіндегі Тапсырысты өңдеуде жүзеге асырылады. Тапсырысты жеткізу қызметіне беру, аралық қоймаға жылжыту және т.б. артында статус үлгісі бар. Тұтас монолит, тіпті екеуі, сонымен қатар жеткізуге арналған API жиынтығы бар. Олар жеткізу туралы көбірек біледі.

Бұл ұқсас аймақтар сияқты, бірақ BOB жүйесіндегі Тапсырысты өңдеу және Жеткізу жүйесінде әртүрлі күйлер бар. Мысалы, кейбір курьерлік қызметтер аралық мәртебелерді емес, тек соңғыларын жібереді: «жеткізілді» немесе «жоғалды». Басқалары, керісінше, тауарлардың қозғалысы туралы егжей-тегжейлі хабарлайды. Әркімнің өз валидация ережелері бар: кейбіреулер үшін электрондық пошта жарамды, яғни ол өңделеді; басқалары үшін бұл жарамсыз, бірақ тапсырыс әлі де өңделеді, өйткені байланыс үшін телефон нөмірі бар және біреу мұндай тапсырыс мүлдем өңделмейді деп айтады.

Деректер ағыны

Кафка жағдайында деректер ағынын ұйымдастыру мәселесі туындайды. Бұл тапсырма бірнеше тармаққа негізделген стратегияны таңдауды қамтиды; олардың барлығын қарастырайық.

Бір тақырыпта ма, әлде әртүрлі тақырыпта ма?

Бізде оқиғаның сипаттамасы бар. BOB-те біз осындай және осындай тапсырысты жеткізу керек деп жазамыз және мыналарды көрсетеміз: тапсырыс нөмірі, оның құрамы, кейбір SKU және штрих-кодтар және т.б. Тауар қоймаға келгенде, жеткізілім күйлерді, уақыт белгілерін және қажеттінің бәрін ала алады. Бірақ содан кейін біз BOB ішіндегі осы деректер бойынша жаңартуларды алғымыз келеді. Бізде жеткізуден деректерді алудың кері процесі бар. Бұл бірдей оқиға ма? Әлде бұл өз тақырыбына лайық бөлек алмасу ма?

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

Жаңа өріс немесе жаңа оқиға?

Бірақ егер сіз бірдей оқиғаларды қолдансаңыз, онда басқа мәселе туындайды. Мысалы, барлық жеткізу жүйелері BOB жасай алатын DTO түрін жасай алмайды. Біз оларға идентификаторды жібереміз, бірақ олар оны сақтамайды, себебі бұл оларға қажет емес және оқиға автобусы процесін бастау тұрғысынан бұл өріс қажет.

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

Тағы бір мәселе - қадамдық дамудың азғыруы. Оқиғаға бірдеңе қосу керек деп айтып жатыр, бәлкім, ойлансақ, бұл бөлек оқиға болуы керек еді. Бірақ біздің схемада бөлек оқиға бөлек тақырып. Жеке тақырып - мен жоғарыда сипаттаған бүкіл процесс. Әзірлеуші ​​жай ғана JSON схемасына басқа өрісті қосып, оны қалпына келтіргісі келеді.

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

Оқиға нұсқасы

Кафкадағы хабарларды тексеру үшін пайдалануға болады Avro, бірақ оған дереу жатып, Confluent пайдалану керек болды. Біздің жағдайда нұсқаны жасауда абай болу керек. Репликация журналынан хабарларды қайта оқу әрқашан мүмкін болмайды, себебі үлгіде «солға» қалды. Негізінде, модель кері үйлесімді болатындай нұсқаларды құрастыру керек: мысалы, өрісті уақытша міндетті емес етіп жасаңыз. Айырмашылықтар тым күшті болса, біз жаңа тақырыпта жаза бастаймыз және ескісін оқып болғаннан кейін клиенттерді ауыстырамыз.

Бөлімдерді оқудың кепілдендірілген реті

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

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

Кафка оларды қалай бөледі? Әрбір хабарламаның денесі (біз JSON сақтаймыз) және кілті бар. Сіз бұл пернеге хэш функциясын қоса аласыз, ол хабарлама қай бөлімге түсетінін анықтайды.

Төлемді қайтару жағдайында бұл маңызды, егер біз екі бөлімді алсақ, параллель тұтынушы екінші оқиғаны біріншіден бұрын өңдеп, қиындық туындауы мүмкін. Хэш функциясы бірдей кілті бар хабарламалардың бір бөлімде аяқталуын қамтамасыз етеді.

Оқиғалар командаларға қарсы

Бұл біз кездестірген тағы бір мәселе. Оқиға - белгілі бір оқиға: біз бір жерде бірдеңе болды деп айтамыз (бірдеңе_болды), мысалы, элемент жойылды немесе ақша қайтарылды. Егер біреу осы оқиғаларды тыңдаса, "элемент жойылды" дегенге сәйкес ақшаны қайтару ұйымы құрылады және параметрлердің бір жерінде "қайтару болды" деп жазылады.

Бірақ, әдетте, оқиғаларды құрастырған кезде, сіз оларды босқа жазғыңыз келмейді - сіз біреу оларды оқитынына сенесіз. Бірдеңе_болды (тауар_болдырылды, қайтарылған_қайтарылды) емес, бірдеңе_орындалуы керек деп жазуға үлкен азғыру бар. Мысалы, зат қайтаруға дайын.

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

Кафкадағы асинхронды API көмегімен Қайтару құралы қызметін әзірлеу тәжірибесі

RabbitMQ-дегі асинхронды алмасуда сіз хабарламаны оқыған кезде http сайтына өтіңіз, сізде жауап бар - кем дегенде хабарлама алынған. Сіз Кафкаға жазған кезде, сіз Кафкаға жазған хабарламаңыз бар, бірақ сіз оның қалай өңделгені туралы ештеңе білмейсіз.

Сондықтан, біздің жағдайда жауап беру іс-шарасын енгізіп, мониторингті орнатуға тура келді, егер сонша оқиға жіберілсе, осындай уақыттан кейін жауап беру оқиғаларының саны бірдей болуы керек. Егер бұл орындалмаса, бірдеңе дұрыс емес сияқты. Мысалы, егер біз "қайтаруға_дайын_элемент" оқиғасын жіберсек, ақшаны қайтару жасалады, ақша клиентке қайтарылады және "ақша_қайтарылды" оқиғасы бізге жіберіледі деп күтеміз. Бірақ бұл нақты емес, сондықтан бақылау қажет.

Нюанстар

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

Біз бұл туралы білдік, оған сендік, бірақ солай болды. Бұл оқиға оқиғалар-автобус тұрғысынан жарамды болғандықтан болды, оқиға қосымшаның валидаторы тұрғысынан жарамды болды, бірақ PostgreSQL тұрғысынан ол жарамсыз болды, өйткені біздің бір жүйеде UNSIGNED INT бар MySQL және жаңадан жазылған жүйеде PostgreSQL тек INT-мен бірге болды. Оның өлшемі сәл кішірек, ал Id сәйкес келмеді. Симфони ерекше жағдайда қайтыс болды. Біз, әрине, ерекше жағдайды ұстадық, өйткені біз оған сүйендік және осы офсетті жасамақпыз, бірақ бұған дейін біз мәселенің есептегішін арттырғымыз келді, себебі хабарлама сәтсіз өңделді. Бұл жобадағы есептегіштер де дерекқорда және Symfony дерекқормен байланысты қазірдің өзінде жауып қойған, ал екінші ерекшелік офсетті орындау мүмкіндігінсіз бүкіл процесті жойды.

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

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

Тағы бір нюанс - репликация журналына қарсы rdkafka.so - жобамыздың ерекшелігіне байланысты. Біз РНР-ді қолданамыз, ал РНР-де, әдетте, барлық кітапханалар Кафкамен rdkafka.so репозиторийі арқылы байланысады, содан кейін қандай да бір орауыш бар. Бәлкім, бұл біздің жеке қиындықтарымыз шығар, бірақ бұрын оқыған нәрселердің бір бөлігін қайта оқу оңай емес екені белгілі болды. Жалпы, бағдарламалық қамтамасыз ету проблемалары болды.

Бөлімдермен жұмыс істеу ерекшеліктеріне оралсақ, ол құжаттамада тікелей жазылған тұтынушылар >= тақырып бөлімдері. Бірақ бұл туралы мен қалағанымнан әлдеқайда кеш білдім. Егер сіз масштабтауды және екі тұтынушыға ие болғыңыз келсе, сізге кемінде екі бөлім қажет. Яғни, сізде 20 мың хабарлама жинақталған бір бөлім болса және сіз жаңасын жасасаңыз, хабарламалар саны жақында теңестірілмейді. Сондықтан, екі параллель тұтынушыға ие болу үшін бөлімдермен айналысу керек.

Бақылау

Менің ойымша, біз оны бақылау тәсілі қолданыстағы тәсілде қандай проблемалар бар екенін одан да айқынырақ болады.

Мысалы, біз дерекқордағы қанша өнім жақында күйін өзгерткенін есептейміз және сәйкесінше, осы өзгерістер негізінде оқиғалар орын алуы керек еді және біз бұл нөмірді мониторинг жүйемізге жібереміз. Содан кейін Кафкадан біз екінші санды аламыз, қанша оқиға нақты жазылған. Әлбетте, бұл екі санның арасындағы айырмашылық әрқашан нөлге тең болуы керек.

Кафкадағы асинхронды API көмегімен Қайтару құралы қызметін әзірлеу тәжірибесі

Сонымен қатар, сіз продюсердің қалай жұмыс істеп жатқанын, оқиғалар-автобус хабарламаларын алған-алмағанын және тұтынушының қалай жұмыс істейтінін бақылауыңыз керек. Мысалы, төмендегі диаграммаларда Қайтару құралы жақсы жұмыс істейді, бірақ BOB-те кейбір мәселелер бар (көк шыңдар).

Кафкадағы асинхронды API көмегімен Қайтару құралы қызметін әзірлеу тәжірибесі

Мен жоғарыда тұтынушылар тобының артта қалуын айттым. Шамамен айтқанда, бұл оқылмаған хабарламалардың саны. Тұтастай алғанда, біздің тұтынушылар тез жұмыс істейді, сондықтан лаг әдетте 0 болады, бірақ кейде қысқа мерзімді шыңы болуы мүмкін. Кафка мұны қораптан тыс жасай алады, бірақ белгілі бір интервалды орнату керек.

Жоба бар BurrowБұл сізге Кафка туралы көбірек ақпарат береді. Ол жай ғана осы топтың жұмысының күйін беру үшін тұтынушылар тобының API интерфейсін пайдаланады. «Жарайды» және «Сәтсіз» дегеннен басқа, ескерту бар және сіз тұтынушыларыңыздың өндіріс қарқынына төтеп бере алмайтынын біле аласыз - олардың жазылғанды ​​тексеруге уақыты жоқ. Жүйе өте ақылды және пайдалану оңай.

Кафкадағы асинхронды API көмегімен Қайтару құралы қызметін әзірлеу тәжірибесі

API жауабы осылай көрінеді. Мұнда bob-live-fifa тобы, refund.update.v1 бөлімі, күйі жақсы, 0 лаг - соңғы соңғы офсет осындай және осындай.

Кафкадағы асинхронды API көмегімен Қайтару құралы қызметін әзірлеу тәжірибесі

Бақылау SLA бойынша жаңартылған (кептеліп қалған) Мен айтып кеттім. Мысалы, өнім қайтаруға дайын деген күйге өзгерді. Біз Cron орнатамыз, ол егер бұл нысан 5 минут ішінде қайтарылмаса (ақшаны төлем жүйелері арқылы өте тез қайтарамыз), онда бірдеңе дұрыс болмады және бұл міндетті түрде қолдау көрсетуге арналған жағдай. Сондықтан, біз жай ғана осындай нәрселерді оқитын Cron-ды аламыз, ал егер олар 0-ден үлкен болса, ол ескерту жібереді.

Қорытындылай келе, оқиғаларды пайдалану ыңғайлы болған кезде:

  • ақпарат бірнеше жүйеге қажет;
  • өңдеу нәтижесі маңызды емес;
  • аз оқиғалар немесе шағын оқиғалар бар.

Мақалада өте нақты тақырып бар сияқты - Кафкадағы асинхронды API, бірақ соған байланысты мен бірден көп нәрсені ұсынғым келеді.
Алдымен, келесі Жоғары жүктеме++ қарашаға дейін күтуіміз керек, сәуірде Петербург нұсқасы болады, ал маусымда Новосибирскіде жоғары жүктемелер туралы айтатын боламыз.
Екіншіден, баяндаманың авторы Сергей Зайка – білімді басқару жөніндегі жаңа конференциямыздың Бағдарламалық комитетінің мүшесі. KnowledgeConf. Конференция бір күндік, 26 сәуірде өтеді, бірақ оның бағдарламасы өте қарқынды.
Ал мамыр айында болады PHP Ресей и RIT++ (DevOpsConf қосылған) - сіз сондай-ақ сол жерде өз тақырыбыңызды ұсына аласыз, тәжірибеңіз туралы сөйлесе аласыз және толтырылған конустарыңыз туралы шағым жасай аласыз.

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

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