Өзара әрекеттесетін қызмет модульдері контекстінде сөзсіз сұрақ туындайды: байланыс қандай ережелер бойынша жүзеге асады? АТ өнімдерінде «келісімшарт» жүйелер арасында қандай деректер ағыны және олардың қалай жіберілетіні туралы ресми түсінікті білдіреді. Бұл деректер пішімін (JSON, Protobuf, т.б.), құрылымдық элементтерді (өрістер, деректер түрлері), байланыс хаттамасын (REST, gRPC, хабарлар кезегі) және басқа сипаттамаларды қамтиды.
Келісім-шарт ашықтықты (ненің қабылданғанын және жіберілетінін барлығы біледі), болжамдылықты (біз келісім-шартты жаңартып, нұсқаларды сақтай аламыз) және сенімділікті (егер біз жақсы басқарылатын өзгертулер енгізсек, жүйеміз сәтсіздікке ұшырамайды) қамтамасыз етеді.
Іс жүзінде барлығы микросервистер, «келісімшарттар» және API интерфейстері туралы айтатынына қарамастан, біз жиі адамдар мына тәсілді қабылдайтынын көреміз: «Неліктен API құрудың орнына дерекқорда ортақ кесте жасамасқа?»
Сондықтан, деректер алмасу үшін ортақ кестені пайдалану тиімді және жылдам нәтижелер алу үшін оңтайландырылған болып көрінуі мүмкін, бірақ ол ұзақ мерзімді перспективада әртүрлі техникалық және ұйымдастырушылық қиындықтарды тудырады. Дегенмен, командалар деректер алмасу үшін ортақ кестелерді таңдағанда, олар іске асыру кезінде көптеген мәселелерге тап болуы мүмкін.
Қызметтер REST/gRPC/GraphQL арқылы байланысқанда, олардың ресми анықтамасы болады: OpenAPI (Swagger), протобуф схемалары немесе GraphQL схемалары. Олар қандай ресурстар (соңғы нүктелер) қолжетімді, қандай өрістер күтілетінін, олардың түрлерін және сұрау/жауап пішімдерін егжей-тегжейлі анықтайды. «Ортақ кесте» келісім-шарт ретінде әрекет еткенде, ресми сипаттама болмайды: Келісімшарттың ресми сипаттамасы жоқ; тек кесте схемасы (DDL) қол жетімді және тіпті ол жақсы құжатталмаған. Кесте құрылымының кез келген шағын өзгертулері (мысалы, бағанды қосу немесе жою, деректер түрлерін өзгерту) осы кестеден оқитын немесе оған жазатын басқа топтарға әсер етуі мүмкін.
API нұсқасын жасау қалыпты тәжірибе: бізде v1, v2 және т.б. болуы мүмкін және біз кері үйлесімділікті сақтай аламыз, содан кейін клиенттерді жаңа нұсқаларға біртіндеп жылжыта аламыз. Дерекқор кестелері үшін бізде тек DDL операциялары бар (мысалы, ALTER TABLE
), олар нақты ДҚ қозғалтқышымен тығыз байланыстырылған және тасымалдауларды мұқият өңдеуді қажет етеді.
Тұтынушыларға сұрауларын жаңартуды талап ететін схема өзгерістері туралы ескертулер жібере алатын орталықтандырылған жүйе жоқ. Нәтижесінде, «үстел астындағы» мәмілелер орын алуы мүмкін: біреу чатта «Ертең X бағанын Y бағанына ауыстырамыз» деп жариялай алады, бірақ барлығы дер кезінде дайын болатынына кепілдік жоқ.
Нақты анықталған API болғанда, оның кімге тиесілі екені анық: API жариялаушысы ретінде қызмет ететін қызмет. Бірнеше командалар бір дерекқор кестесін пайдаланған кезде құрылымды кім анықтайтыны және қандай өрістерді сақтау керек және оларды қалай түсіндіру керектігі туралы түсінбеушілік туындайды. Нәтижесінде кесте «ешкімнің меншігіне» айналуы мүмкін және әрбір өзгеріс квестке айналады: «Егер олар ескі бағанды пайдаланып жатқан болса, біз сол басқа топпен тексеруіміз керек!»
Көптеген командалар МБ-ға қол жеткізе алатын болса, кестеде кім оқи және жаза алатынын бақылау қиын. Рұқсат етілмеген қызметтер олар үшін арналмаған болса да, деректерге қол жеткізу мүмкіндігі бар. API көмегімен мұндай мәселелерді басқару оңайырақ: қол жеткізу құқықтарын басқара аласыз (кім қандай әдістерге қоңырау шала алады), аутентификация мен авторизацияны пайдалана аласыз және кім не шақырғанын бақылай аласыз. Кестемен бұл әлдеқайда күрделі.
Деректерге кез келген ішкі модификациялар (индекстерді қайта ұйымдастыру, кестені бөлу, ДҚ өзгерту) жаһандық проблемаға айналады. Кесте жалпыға ортақ интерфейс ретінде қызмет етсе, иесі барлық сыртқы оқырмандар мен жазушыларға қауіп төндірмей, ішкі өзгерістерді жасай алмайды.
Бұл ең ауыр аспект: келесі күні схеманың өзгеретіні туралы басқа командаға қалай хабарлау керек?
Бірнеше команда маңызды деректерді таңдау және жаңарту үшін ортақ кестені пайдаланғанда, ол оңай «шайқас алаңына» айналуы мүмкін. Нәтижесінде бизнес логикасы әртүрлі қызметтерге шашыраңқы болады және деректер тұтастығын орталықтандырылған бақылау жоқ. Белгілі бір өрістің неліктен белгілі бір түрде сақталатынын, оны кім жаңарта алатынын және бос қалдырылған жағдайда не болатынын білу өте қиын болады.
Мысалы, кесте үзілді делік: Айталық, нашар деректер бар немесе біреу кейбір маңызды жолдарды құлыпты алды. Ақаулықтың көзін анықтау көбінесе ДҚ рұқсаты бар әрбір топтан мәселеге қандай сұрау себеп болғанын анықтауды сұрауды талап етеді. Бұл жиі анық емес: бұл бір топтың сұрауы дерекқорды құлыптаған болуы мүмкін дегенді білдіреді, ал басқа топтың сұрауы байқалатын қатені тудырады.
Ортақ дерекқор - бұл бір сәтсіздік нүктесі. Егер ол төмендесе, көптеген қызметтер онымен бірге жойылады. Бір қызметтің ауыр сұрауларына байланысты дерекқорда өнімділікке қатысты мәселелер туындағанда, барлық қызметтерде ақаулар туындайды. Нақты API интерфейстері мен деректерге иелік ету үлгісінде әрбір топ өз қызметінің қол жетімділігі мен өнімділігін меңгереді, сондықтан бір құрамдастағы сәтсіздік басқаларға таралмайды.
Жалпы ымыра: «Біз сізге тек оқуға арналған репликаны береміз, осылайша сіз біздің негізгі дерекқорымызға әсер етпейсіз.» Алдымен бұл кейбір жүктеме мәселелерін шешуі мүмкін, бірақ:
Заманауи дизайн тәжірибелері (мысалы, «Алдымен API» немесе «Алдымен келісім-шарт») интерфейстің ресми анықтамасынан басталады. OpenAPI/Swagger, protobuf немесе GraphQL схемалары пайдаланылады. Осылайша, адамдар да, машиналар да қандай соңғы нүктелердің қолжетімді екенін, қандай өрістер қажет екенін және қандай деректер түрлері пайдаланылатынын біледі.
Микросервистердің (немесе тіпті модульдік) архитектурасында әрбір қызмет өзінің деректерін толығымен иеленеді деген болжам бар. Ол құрылымды, сақтауды және бизнес логикасын анықтайды және сол API-ге барлық сыртқы қатынас үшін API ұсынады. Ешкім «біреудің» дерекқорына қол тигізе алмайды: тек ресми соңғы нүктелер немесе оқиғалар. Бұл өзгерістер туралы сөз болған кезде өмірді жеңілдетеді және кім кінәлі екені әрқашан анық болады.
GET /items
, POST /items
, т.б. сияқты соңғы нүктелерді жариялайды және клиенттер нақты анықталған деректер схемасымен (DTO) сұраулар жасайды.
Қандай модель болса да, интерфейсте нұсқаны басқаруды жүзеге асыру мүмкін және маңызды. Мысалы:
Негізгі принцип - деректерді иеленетін топ оны қалай сақтау және басқару керектігін шешеді, бірақ олар басқа қызметтерге тікелей жазу рұқсатын бермеуі керек. Басқалары шетелдік деректерді өңдеуге қарағанда API арқылы өтуі керек. Бұл жауапкершіліктің анық бөлінуін береді: Егер А қызметі бұзылса, оны жөндеу көршілерінің емес, А қызметінің міндеті.
Бір қарағанда, егер бәрі бір командада болса, API көмегімен неге қиындату керек? Шындығында, модульдерге бөлінген бір өнім болса да, ортақ кесте бірдей мәселелерге әкелуі мүмкін.
Мысалы, Тапсырыстар қызметі тапсырыстар кестесінің иесі болып табылады, ал Төлем қызметі сол кестеге тікелей кірмейді – ол тапсырыс мәліметтерін алу немесе тапсырысты төленген деп белгілеу үшін Тапсырыстар қызметінің соңғы нүктелеріне қоңырау шалады.
Жоғары деңгейде, екі немесе одан да көп командалар әртүрлі салаларға жауапты болған кезде, принциптер өзгеріссіз қалады. Мысалы:
Егер В тобы А командасына тиесілі «Каталог» кестесін тікелей сұраса, А-дағы кез келген ішкі схема өзгерістері (мысалы, өрістерді қосу, құрылымды өзгерту) В тобына әсер етуі мүмкін.
Тиісті тәсіл API пайдалану болып табылады: A тобы GET /catalog/items
, GET /catalog/items/{id}
және т.б. сияқты соңғы нүктелерді қамтамасыз етеді, ал В тобы сол әдістерді пайдаланады. Егер А ескі және жаңарақ нұсқаларды қолдаса, олар /v2 шығара алады, бұл B тасымалдауға уақыт береді.
Ресми келісім-шартпен барлық өзгерістер көрінеді: Swagger/OpenAPI, .proto файлдары немесе оқиға құжаттамасында. Кез келген жаңартуды қажетінше кері үйлесімділік стратегияларымен алдын ала талқылауға, дұрыс тексеруге және жоспарлауға болады.
Бір қызметтегі өзгерістер басқаларға азырақ әсер етеді. Егер олар жаңа және ескі өрістерді немесе соңғы нүктелерді дұрыс басқарса, біркелкі өтуді қамтамасыз етсе, команда басқа біреуді «сындыру» туралы алаңдамауы керек.
API шлюздері, аутентификация және авторизация (JWT, OAuth) қызметтер үшін стандартты болып табылады, бірақ ортақ кестемен мүмкін емес дерлік. Қол жеткізуді дәл реттеу (қай әдістерге кім қоңырау шала алады), журналдарды жүргізу, пайдалану статистикасын қадағалау және квоталарды енгізу оңайырақ. Бұл жүйені қауіпсіз және болжамды етеді.
Дерекқордағы ортақ кесте қызметтер арасындағы келісім емес, келісім-шарт ретінде қарастырылмайды. Көптеген мәселелер (күрделі нұсқалар, хаотикалық өзгерістер, түсініксіз иелік, қауіпсіздік және өнімділік тәуекелдері) бұл тәсілді ұзақ мерзімді перспективада жарамсыз етеді.
Дұрыс тәсіл - Бірінші Келісімшарт , ол формальды дизайн арқылы өзара әрекеттесуді анықтауды және әрбір қызмет өз деректерінің иесі болып қалатын принципті ұстануды білдіреді. Бұл техникалық қарызды азайтуға көмектесіп қана қоймайды, сонымен қатар мөлдірлікті арттырады, өнімді әзірлеуді жылдамдатады және дерекқор схемалары бойынша өртті сөндіруге араласпай-ақ қауіпсіз өзгертулерге мүмкіндік береді.
Бұл техникалық мәселе (жобалау және біріктіру жолы) және ұйымдастыру мәселесі (командалар қалай байланысады және өзгерістерді басқарады). Егер сіз өніміңіздің дерекқор схемаларына қатысты шексіз төтенше жағдайларға тап болмай өскенін қаласаңыз, онда дерекқорға тікелей қол жеткізу емес, келісімшарттар тұрғысынан ойлауды бастау керек.