Микросервис архитектурасын дамытуға қатысты жобаларда CI/CD жағымды мүмкіндік санатынан шұғыл қажеттілік санатына ауысады. Автоматтандырылған тестілеу үздіксіз интеграцияның құрамдас бөлігі болып табылады, оған құзыретті тәсіл командаға отбасымен және достарымен көптеген жағымды кештер сыйлай алады. Әйтпесе, жоба ешқашан аяқталмау қаупі бар.
Жалған нысандармен бірлік сынақтарымен бүкіл микросервис кодын қамтуға болады, бірақ бұл мәселені ішінара ғана шешеді және көптеген сұрақтар мен қиындықтарды қалдырады, әсіресе деректермен жұмысты тестілеу кезінде. Әдеттегідей, ең өзектілері реляциялық дерекқордағы деректердің сәйкестігін тексеру, бұлттық қызметтермен жұмысты тексеру және жалған нысандарды жазу кезінде қате болжамдар жасау.
Осының барлығын және тағы басқаларын Docker контейнерінде бүкіл микросервисті сынау арқылы шешуге болады. Сынақтардың жарамдылығын қамтамасыз етудің сөзсіз артықшылығы - өндіріске кіретін бірдей Docker кескіндері сынақтан өтеді.
Бұл тәсілді автоматтандыру бірқатар проблемаларды ұсынады, олардың шешімі төменде сипатталады:
- бір докер хостындағы параллель тапсырмалардың қақтығыстары;
- тест итерациялары кезінде дерекқордағы идентификатор қайшылықтары;
- микросервистердің дайын болуын күту;
- журналдарды сыртқы жүйелерге біріктіру және шығару;
- шығыс HTTP сұрауларын тексеру;
- веб-розетканы тестілеу (SignalR көмегімен);
- OAuth аутентификациясын және авторизациясын сынау.
Бұл мақалаға негізделген
Бұл мақалада мен Docker жүйесінде сынақтан өтіп жатқан қызметті, дерекқорды және Amazon AWS қызметтерін іске қосу үшін сценарийді қалай пайдалану керектігін, содан кейін Postman жүйесіндегі сынақтарды және олар аяқталғаннан кейін жасалған контейнерлерді тоқтату және жою туралы айтып беремін. Тесттер код өзгерген сайын орындалады. Осылайша, біз әрбір нұсқаның AWS дерекқорымен және қызметтерімен дұрыс жұмыс істейтініне көз жеткіземіз.
Бірдей сценарийді әзірлеушілердің өздері Windows жұмыс үстелінде де, Linux астындағы Gitlab CI серверінде де басқарады.
Негізді болу үшін жаңа сынақтарды енгізу қосымша құралдарды әзірлеушінің компьютерінде немесе тестілеу орындалатын серверде орнатуды қажет етпеуі керек.Docker бұл мәселені шешеді.
Сынақ келесі себептерге байланысты жергілікті серверде орындалуы керек:
- Желі ешқашан толық сенімді бола алмайды. Мың сұраудың біреуі орындалмауы мүмкін;
Бұл жағдайда автоматты сынақ жұмыс істемейді, жұмыс тоқтатылады және журналдардан себебін іздеуге тура келеді; - Кейбір үшінші тарап қызметтері тым жиі сұрауларға рұқсат бермейді.
Сонымен қатар, стендті пайдалану қажет емес, себебі:
- Стенд тек ондағы қате кодпен ғана емес, сонымен қатар дұрыс код өңдей алмайтын деректермен де бұзылуы мүмкін;
- Сынақтың өзі кезінде сынақ жасаған барлық өзгерістерді қайтаруға қанша тырысқанымызбен, бірдеңе дұрыс емес болуы мүмкін (әйтпесе, не үшін сынақ керек?).
Жоба және процесті ұйымдастыру туралы
Біздің компания Amazon AWS бұлтында Docker жүйесінде жұмыс істейтін микросервис веб-қосымшасын әзірледі. Жобада бірлік сынақтары қолданылған, бірақ бірлік сынақтары анықтамайтын қателер жиі орын алды. Дерекқормен және Amazon қызметтерімен бірге тұтас микросервисті сынау қажет болды.
Жоба стандартты үздіксіз интеграциялау процесін пайдаланады, ол микросервисті әрбір міндеттемемен сынауды қамтиды. Тапсырманы тағайындағаннан кейін әзірлеуші микросервиске өзгерістер енгізеді, оны қолмен тексереді және барлық қолжетімді автоматтандырылған сынақтарды іске қосады. Қажет болса, әзірлеуші сынақтарды өзгертеді. Мәселелер табылмаса, осы мәселенің филиалына міндеттеме беріледі. Әрбір тапсырмадан кейін сынақтар серверде автоматты түрде іске қосылады. Жалпы филиалға біріктіру және оған автоматты сынақтарды іске қосу сәтті шолудан кейін орын алады. Ортақ филиалдағы сынақтар өтсе, қызмет Amazon Elastic Container Service (орындық) сынақ ортасында автоматты түрде жаңартылады. Стенд барлық әзірлеушілер мен тестерлер үшін қажет және оны бұзу ұсынылмайды. Бұл ортадағы сынақшылар қолмен сынақтарды орындау арқылы түзетуді немесе жаңа мүмкіндікті тексереді.
Жоба архитектурасы
Қолданба оннан астам қызметтен тұрады. Олардың кейбіреулері .NET Core жүйесінде, ал кейбіреулері NodeJs жүйесінде жазылған. Әрбір қызмет Amazon Elastic Container Service ішіндегі Docker контейнерінде жұмыс істейді. Олардың әрқайсысында Postgres дерекқоры бар, ал кейбіреулерінде Redis бар. Жалпы мәліметтер базасы жоқ. Егер бірнеше қызметке бірдей деректер қажет болса, онда бұл деректер өзгерген кезде осы қызметтердің әрқайсысына SNS (Simple Notification Service) және SQS (Amazon Simple Queue Service) арқылы жіберіледі және қызметтер оны өздерінің жеке дерекқорларында сақтайды.
SQS және SNS
SQS HTTPS протоколы арқылы хабарламаларды кезекке қоюға және кезектен хабарларды оқуға мүмкіндік береді.
Бірнеше қызмет бір кезекті оқыса, әрбір хабарлама тек біреуіне келеді. Бұл олардың арасында жүктемені бөлу үшін бір қызметтің бірнеше данасын іске қосқанда пайдалы.
Әрбір хабардың бірнеше қызметтерге жеткізілуін қаласаңыз, әрбір алушының өз кезегі болуы керек және SNS хабарларды бірнеше кезекке көшіру үшін қажет.
SNS жүйесінде сіз тақырыпты жасайсыз және оған жазыласыз, мысалы, SQS кезегі. Тақырыпқа хабарлама жіберуге болады. Бұл жағдайда хабарлама осы тақырыпқа жазылған әрбір кезекке жіберіледі. SNS хабарламаларды оқу әдісі жоқ. Түзету немесе тестілеу кезінде SNS-ге не жіберілгенін білу қажет болса, SQS кезегін жасап, оны қалаған тақырыпқа жазып, кезекті оқуға болады.
API шлюзі
Көптеген қызметтерге Интернеттен тікелей қол жеткізу мүмкін емес. Қол жеткізу рұқсат құқықтарын тексеретін API шлюзі арқылы жүзеге асырылады. Бұл да біздің қызметіміз және ол үшін де сынақтар бар.
Уведомления в реальном времени
Қолданба пайдаланады
Белгілі тестілеу тәсілі
Бірлік сынақтары дерекқор сияқты нәрселерді жалған нысандармен ауыстырады. Егер микросервис, мысалы, сыртқы кілті бар кестеде жазба жасауға әрекеттенсе және сол кілт сілтеме жасаған жазба жоқ болса, онда сұрауды аяқтау мүмкін емес. Бірлік сынақтары мұны анықтай алмайды.
В
Жадтағы дерекқор - Entity Framework қолдайтын ДҚБЖ бірі. Ол тестілеу үшін арнайы жасалған. Мұндай дерекқордағы деректер оны пайдалану процесі аяқталғанша ғана сақталады. Ол кестелерді құруды қажет етпейді және деректердің тұтастығын тексермейді.
Жалған нысандар сынақ әзірлеушісі оның қалай жұмыс істейтінін түсінетін дәрежеде ғана ауыстыратын сыныпты үлгілейді.
Сынақты іске қосу кезінде Postgres-ті автоматты түрде іске қосу және тасымалдауды орындау жолы Microsoft мақаласында көрсетілмеген. Менің шешімім мұны жасайды және оған қоса, микросервистің өзіне сынақтар үшін арнайы код қосылмайды.
Шешімге көшейік
Әзірлеу барысында бірлік сынақтары барлық мәселелерді дер кезінде табу үшін жеткіліксіз екендігі белгілі болды, сондықтан бұл мәселеге басқа қырынан қарау туралы шешім қабылданды.
Сынақ ортасын орнату
Бірінші тапсырма - сынақ ортасын орналастыру. Микросервисті іске қосу үшін қажетті қадамдар:
- Жергілікті орта үшін сыналатын қызметті теңшеңіз, орта айнымалы мәндерінде дерекқорға және AWS-ке қосылу мәліметтерін көрсетіңіз;
- Postgres бағдарламасын іске қосыңыз және Liquibase іске қосу арқылы тасымалдауды орындаңыз.
Реляциялық ДҚБЖ-да мәліметтер базасына деректерді жазбас бұрын деректер схемасын, басқаша айтқанда, кестелерді құру керек. Қолданбаны жаңарту кезінде кестелерді жаңа нұсқа пайдаланатын пішінге және жақсырақ деректерді жоғалтпай әкелу керек. Бұл миграция деп аталады. Бастапқыда бос дерекқорда кестелер жасау көшірудің ерекше жағдайы болып табылады. Көшіру қолданбаның өзіне енгізілуі мүмкін. .NET және NodeJS екеуінде де тасымалдау құрылымдары бар. Біздің жағдайда, қауіпсіздік мақсатында микросервистер деректер схемасын өзгерту құқығынан айырылады және тасымалдау Liquibase көмегімен жүзеге асырылады. - Amazon LocalStack іске қосыңыз. Бұл үйде іске қосу үшін AWS қызметтерін іске асыру. Docker Hub жүйесінде LocalStack үшін дайын кескін бар.
- LocalStack бағдарламасында қажетті нысандарды жасау үшін сценарийді іске қосыңыз. Shell сценарийлері AWS CLI пайдаланады.
Жобада тестілеу үшін қолданылады
Автоматты сынақ қалай жұмыс істейді?
Тестілеу кезінде Docker-те барлығы жұмыс істейді: сыналған қызмет, Postgres, тасымалдау құралы және Postman, дәлірек айтқанда оның консольдық нұсқасы - Ньюман.
Docker бірқатар мәселелерді шешеді:
- Хост конфигурациясынан тәуелсіздік;
- Тәуелділіктерді орнату: Docker кескіндерді Docker Hub жүйесінен жүктейді;
- Жүйені бастапқы күйіне қайтару: жай ғана контейнерлерді алып тастау.
Docker-құрастыру контейнерлерді интернеттен оқшауланған виртуалды желіге біріктіреді, онда контейнерлер бір-бірін домен атаулары бойынша табады.
Сынақ қабық сценарийімен басқарылады. Windows жүйесінде сынақты орындау үшін git-bash қолданамыз. Осылайша, Windows және Linux үшін бір сценарий жеткілікті. Git және Docker-ті жобадағы барлық әзірлеушілер орнатады. Windows жүйесіне Git орнату кезінде git-bash орнатылады, сондықтан барлығында да бар.
Сценарий келесі қадамдарды орындайды:
- Докер кескіндерін құру
docker-compose build
- Деректер базасын және LocalStack іске қосу
docker-compose up -d <контейнер>
- Деректер базасын көшіру және LocalStack дайындау
docker-compose run <контейнер>
- Сынақтағы қызметті іске қосу
docker-compose up -d <сервис>
- Тестті орындау (Ньюман)
- Барлық контейнерлерді тоқтату
docker-compose down
- Нәтижелерді Slack ішінде жариялау
Бізде жасыл құсбелгі немесе қызыл крест және журналға сілтеме бар хабарламалар өтетін чат бар.
Келесі Docker кескіндері осы қадамдарға қатысады:
- Тексерілетін қызмет өндіріске арналған кескінмен бірдей. Сынақ үшін конфигурация орта айнымалылары арқылы жасалады.
- Postgres, Redis және LocalStack үшін Docker Hub-дан дайын кескіндер пайдаланылады. Сондай-ақ Liquibase және Newman үшін дайын суреттер бар. Біз өз файлдарымызды олардың қаңқасына салып, сол жерге файлдарымызды қосамыз.
- LocalStack дайындау үшін сіз дайын AWS CLI кескінін пайдаланасыз және оның негізінде сценарийі бар кескінді жасайсыз.
Пайдалану
Сіз кездесуі мүмкін мәселелер
Дайындықты күту
Қызметі бар контейнер жұмыс істеп тұрғанда, бұл оның қосылымдарды қабылдауға дайын екенін білдірмейді. Байланыстың жалғасуын күтуіңіз керек.
Бұл мәселе кейде сценарий арқылы шешіледі
шешім: SQS және SNS екеуінен де 200 жауапты күтетін LocalStack дайындау сценарийлері.
Параллель тапсырма қақтығыстары
Бірнеше сынақтар бір Docker хостында бір уақытта жұмыс істей алады, сондықтан контейнер мен желі атаулары бірегей болуы керек. Сонымен қатар, бір қызметтің әртүрлі филиалдарының сынақтары да бір уақытта жұмыс істей алады, сондықтан олардың атын әрбір құрастыру файлына жазу жеткіліксіз.
шешім: Сценарий COMPOSE_PROJECT_NAME айнымалы мәнін бірегей мәнге орнатады.
Windows мүмкіндіктері
Windows жүйесінде Docker қолданбасын пайдаланған кезде мен бірнеше нәрсені атап өткім келеді, себебі бұл тәжірибелер қателердің неліктен орын алғанын түсіну үшін маңызды.
- Контейнердегі қабық сценарийлерінің Linux жолының соңы болуы керек.
Қабық CR таңбасы синтаксистік қате болып табылады. Қате туралы хабардан бұл жағдай екенін айту қиын. Windows жүйесінде мұндай сценарийлерді өңдеу кезінде сізге тиісті мәтіндік редактор қажет. Бұған қоса, нұсқаны басқару жүйесі дұрыс конфигурациялануы керек.
git осылай конфигурацияланады:
git config core.autocrlf input
- Git-bash стандартты Linux қалталарын эмуляциялайды және exe файлын (соның ішінде docker.exe) шақырған кезде абсолютті Linux жолдарын Windows жолдарымен ауыстырады. Дегенмен, бұл жергілікті құрылғыда емес жолдар үшін (немесе контейнердегі жолдар) мағынасы жоқ. Бұл әрекетті өшіру мүмкін емес.
шешім: жолдың басына қосымша қиғаш сызықты қосыңыз: //bin орнына /bin. Linux мұндай жолдарды түсінеді; ол үшін бірнеше қиғаш сызықтар біреумен бірдей. Бірақ git-bash мұндай жолдарды танымайды және оларды түрлендіруге тырыспайды.
Журнал шығысы
Сынақтарды іске қосқан кезде мен Ньюманның журналдарын да, тексерілетін қызметтен де көргім келеді. Бұл журналдардың оқиғалары өзара байланысты болғандықтан, оларды бір консольде біріктіру екі бөлек файлға қарағанда әлдеқайда ыңғайлы. Ньюман арқылы іске қосылады докер-құрастыруды іске қосу, сондықтан оның шығысы консольде аяқталады. Қызметтің нәтижесі де сол жаққа кететініне көз жеткізу ғана қалады.
Бастапқы шешім жасау болды доккер-құрастыру жалауы жоқ -d, бірақ қабық мүмкіндіктерін пайдаланып, бұл процесті фондық режимге жіберіңіз:
docker-compose up <service> &
Бұл Docker журналдарын үшінші тарап қызметіне жіберу қажет болғанша жұмыс істеді. доккер-құрастыру журналдарды консольге шығаруды тоқтатты. Дегенмен, команда жұмыс істеді доккер бекітіңіз.
шешім:
docker attach --no-stdin ${COMPOSE_PROJECT_NAME}_<сервис>_1 &
Сынақ итерациялары кезінде идентификатор қайшылығы
Тесттер бірнеше итерацияда орындалады. Деректер базасы тазартылмаған. Дерекқордағы жазбалардың бірегей идентификаторлары болады. Сұранымдардағы нақты идентификаторларды жазсақ, біз екінші итерацияда қайшылық аламыз.
Оны болдырмау үшін идентификаторлар бірегей болуы керек немесе сынақ арқылы жасалған барлық нысандар жойылуы керек. Кейбір нысандарды талаптарға байланысты жою мүмкін емес.
шешім: Postman сценарийлерін пайдаланып GUID жасау.
var uuid = require('uuid');
var myid = uuid.v4();
pm.environment.set('myUUID', myid);
Содан кейін сұраудағы таңбаны пайдаланыңыз {{myUUID}}, ол айнымалының мәнімен ауыстырылады.
LocalStack арқылы бірлесіп жұмыс істеу
Егер тексерілетін қызмет SQS кезегін оқитын немесе жазатын болса, оны тексеру үшін сынақтың өзі де осы кезекпен жұмыс істеуі керек.
шешім: пошташыдан LocalStack-қа сұраулар.
AWS қызметтерінің API құжатталған, бұл сұрауларды SDKсіз жасауға мүмкіндік береді.
Егер қызмет кезекке жазса, біз оны оқып, хабарламаның мазмұнын тексереміз.
Егер қызмет SNS хабарларын жіберсе, дайындық кезеңінде LocalStack де кезек жасайды және осы SNS тақырыбына жазылады. Содан кейін бәрі жоғарыда сипатталғанға түседі.
Егер қызметке кезектен хабарды оқу қажет болса, онда алдыңғы сынақ қадамында біз бұл хабарламаны кезекке жазамыз.
Тексеріліп жатқан микросервистен алынған HTTP сұрауларын сынау
Кейбір қызметтер HTTP арқылы AWS емес басқа нәрсемен жұмыс істейді, ал кейбір AWS мүмкіндіктері LocalStack ішінде іске асырылмайды.
шешім: бұл жағдайларда ол көмектесе алады
OAuth аутентификациясын және авторизациясын сынау
Біз OAuth және пайдаланамыз
Қызмет пен OAuth провайдері арасындағы барлық өзара әрекеттестік екі сұрауға түседі: біріншіден, конфигурация сұралады. /.жақсы белгілі/openid-конфигурация, содан кейін конфигурациядағы мекенжайда ашық кілт (JWKS) сұралады. Мұның бәрі статикалық мазмұн.
шешім: Біздің сынақ OAuth провайдері – статикалық мазмұн сервері және ондағы екі файл. Токен бір рет жасалады және Git-ке бекітіледі.
SignalR тестілеуінің мүмкіндіктері
Пошташы веб-розеткалармен жұмыс істемейді. SignalR сынау үшін арнайы құрал жасалды.
SignalR клиенті шолғыштан көп болуы мүмкін. Ол үшін .NET Core астында клиент кітапханасы бар. .NET Core жүйесінде жазылған клиент қосылымды орнатады, түпнұсқалығы расталады және хабарлардың белгілі бір тізбегін күтеді. Егер күтпеген хабарлама алынса немесе қосылым жоғалса, клиент 1 кодымен шығады. Егер соңғы күтілетін хабарлама алынса, клиент 0 кодымен шығады.
Ньюман клиентпен бір уақытта жұмыс істейді. Хабарламалар қажет болғандардың барлығына жеткізілуін тексеру үшін бірнеше клиенттер іске қосылады.
Бірнеше клиентті іске қосу үшін опцияны пайдаланыңыз --масштаб docker-compose пәрмен жолында.
Іске қосу алдында Postman сценарийі барлық клиенттердің қосылымдарды орнатуын күтеді.
Біз қосылымды күту мәселесіне тап болдық. Бірақ серверлер болды, міне, клиент. Басқа көзқарас қажет.
шешім: контейнердегі клиент механизмді пайдаланады
HEALTHCHECK --interval=3s CMD if [ ! -e /healthcheck ]; then false; fi
команда докер тексереді Контейнердің қалыпты күйін, денсаулық күйін және шығу кодын көрсетеді.
Ньюман аяқтағаннан кейін сценарий 0 коды бар клиенті бар барлық контейнерлердің тоқтатылғанын тексереді.
Бақыт бар
Жоғарыда сипатталған қиындықтарды жеңгеннен кейін бізде тұрақты жұмыс сынақтары болды. Сынақтарда әрбір қызмет дерекқормен және Amazon LocalStack-пен өзара әрекеттесетін бір бірлік ретінде жұмыс істейді.
Бұл сынақтар 30+ әзірлеушілер тобын жиі қолданылатын 10+ микросервистердің күрделі өзара әрекеттесуі бар қолданбадағы қателерден қорғайды.
Ақпарат көзі: www.habr.com