Skriptlardan o'z platformamizgacha: biz CIAN-da rivojlanishni qanday avtomatlashtirdik

Skriptlardan o'z platformamizgacha: biz CIAN-da rivojlanishni qanday avtomatlashtirdik

RIT 2019 da bizning hamkasbimiz Aleksandr Korotkov qildi hisobot CIAN-da rivojlanishni avtomatlashtirish haqida: hayot va ishni soddalashtirish uchun biz o'zimizning Integro platformamizdan foydalanamiz. U vazifalarning hayot aylanishini kuzatib boradi, ishlab chiquvchilarni odatiy operatsiyalardan ozod qiladi va ishlab chiqarishdagi xatolar sonini sezilarli darajada kamaytiradi. Ushbu postda biz Aleksandrning hisobotini to'ldiramiz va sizga qanday qilib oddiy skriptlardan ochiq kodli mahsulotlarni o'z platformamiz orqali birlashtirishga o'tganimizni va alohida avtomatlashtirish guruhimiz nima qilayotganini aytib beramiz.
 

Nolinchi daraja

"Nol daraja degan narsa yo'q, men bunday narsani bilmayman"
"Kung Fu Panda" filmidan usta Shifu

CIANda avtomatlashtirish kompaniya tashkil etilganidan 14 yil o'tib boshlangan. O'sha paytda ishlab chiqish guruhida 35 kishi bor edi. Ishonish qiyin, to'g'rimi? Albatta, avtomatlashtirish qandaydir shaklda mavjud edi, lekin uzluksiz integratsiya va kod yetkazib berish uchun alohida yo‘nalish 2015-yilda shakllana boshladi. 

O'sha paytda bizda Linux/Windows serverlarida o'rnatilgan Python, C# va PHPning ulkan monolitlari bor edi. Ushbu yirtqich hayvonni joylashtirish uchun bizda qo'lda ishlaydigan skriptlar to'plami bor edi. Shuningdek, monolitni yig'ish bo'lib o'tdi, bu shoxlarni birlashtirish, nuqsonlarni tuzatish va "qurilishdagi boshqa vazifalar to'plami bilan" qayta qurishda mojarolar tufayli og'riq va azob-uqubatlarni keltirib chiqardi. Soddalashtirilgan jarayon quyidagicha ko'rinardi:

Skriptlardan o'z platformamizgacha: biz CIAN-da rivojlanishni qanday avtomatlashtirdik

Biz bundan mamnun emasdik va biz takrorlanadigan, avtomatlashtirilgan va boshqariladigan qurish va joylashtirish jarayonini yaratmoqchi edik. Buning uchun bizga CI/CD tizimi kerak edi va biz Teamcity-ning bepul versiyasi va Jenkins-ning bepul versiyasini tanladik, chunki biz ular bilan ishladik va ikkalamiz ham funktsiyalar to'plami jihatidan bizga mos keldi. Biz Teamcity-ni eng yangi mahsulot sifatida tanladik. O'sha paytda biz hali mikroservis arxitekturasidan foydalanmagan edik va juda ko'p vazifalar va loyihalarni kutmagan edik.

Biz o'z tizimimiz g'oyasiga keldik

Teamcity-ni amalga oshirish qo'lda ishlashning faqat bir qismini olib tashladi: Pull So'rovlarini yaratish, Jira-dagi maqom bo'yicha muammolarni targ'ib qilish va chiqarish uchun masalalarni tanlash qoladi. Teamcity tizimi endi bunga dosh bera olmadi. Keyinchalik avtomatlashtirish yo'lini tanlash kerak edi. Biz Teamcity-da skriptlar bilan ishlash yoki uchinchi tomon avtomatlashtirish tizimlariga o'tish variantlarini ko'rib chiqdik. Ammo oxir-oqibat biz maksimal moslashuvchanlikka muhtojmiz, deb qaror qildik, bu faqat o'z yechimimiz bilan ta'minlanishi mumkin. Integro deb nomlangan ichki avtomatlashtirish tizimining birinchi versiyasi shunday paydo bo'ldi.

Teamcity qurish va joylashtirish jarayonlarini ishga tushirish darajasida avtomatlashtirish bilan shug'ullanadi, Integro esa rivojlanish jarayonlarini yuqori darajadagi avtomatlashtirishga e'tibor qaratdi. Bitbucket-da bog'langan manba kodini qayta ishlash bilan Jira-dagi muammolar bilan ishlashni birlashtirish kerak edi. Ushbu bosqichda Integro har xil turdagi vazifalar bilan ishlash uchun o'z ish oqimlariga ega bo'la boshladi. 

Biznes-jarayonlarda avtomatlashtirishning kuchayishi tufayli Teamcity-da loyihalar va yugurishlar soni ortdi. Shunday qilib, yangi muammo paydo bo'ldi: bitta bepul Teamcity nusxasi etarli emas edi (3 agent va 100 ta loyiha), biz yana bir misolni (yana 3 ta agent va 100 ta loyiha), keyin boshqasini qo'shdik. Natijada, biz boshqarish qiyin bo'lgan bir nechta klasterlar tizimiga ega bo'ldik:

Skriptlardan o'z platformamizgacha: biz CIAN-da rivojlanishni qanday avtomatlashtirdik

4-instansiya haqida savol tug'ilganda, biz bunday yashashni davom ettira olmasligimizni angladik, chunki 4 ta instansiyani qo'llab-quvvatlashning umumiy xarajatlari endi hech qanday chegarada emas edi. Savol pulli Teamcity-ni sotib olish yoki bepul Jenkins-ni tanlash haqida paydo bo'ldi. Biz misollar va avtomatlashtirish rejalari bo'yicha hisob-kitoblar qildik va Jenkinsda yashashga qaror qildik. Bir necha hafta o'tgach, biz Jenkins-ga o'tdik va bir nechta Teamcity misollarini saqlash bilan bog'liq bosh og'rig'ini yo'q qildik. Shuning uchun biz Integro-ni rivojlantirishga va Jenkins-ni o'zimiz uchun sozlashga e'tibor qaratishimiz mumkin edi.

Asosiy avtomatlashtirishning o'sishi bilan (pull so'rovlarini avtomatik yaratish, Kod qamrovini to'plash va nashr etish va boshqa tekshiruvlar shaklida) imkon qadar qo'lda nashrlardan voz kechish va bu ishni robotlarga topshirish istagi kuchli. Bundan tashqari, kompaniya tez-tez relizlar talab qiladigan kompaniya ichidagi mikroservislarga va bir-biridan alohida o'tishni boshladi. Shunday qilib, biz asta-sekin mikroservislarimizni avtomatik ravishda chiqarishga keldik (hozirda jarayonning murakkabligi sababli monolitni qo'lda chiqarmoqdamiz). Ammo, odatdagidek, yangi murakkablik paydo bo'ldi. 

Biz sinovni avtomatlashtiramiz

Skriptlardan o'z platformamizgacha: biz CIAN-da rivojlanishni qanday avtomatlashtirdik

Chiqarishlarni avtomatlashtirish tufayli, qisman ba'zi sinov bosqichlarini o'tkazib yuborish tufayli ishlab chiqish jarayonlari tezlashdi. Va bu vaqtinchalik sifatni yo'qotishiga olib keldi. Bu arzimas tuyuladi, lekin relizlar tezlashishi bilan birga, mahsulotni ishlab chiqish metodologiyasini o'zgartirish kerak edi. Sinovni avtomatlashtirish, ishlab chiquvchining chiqarilgan kod va undagi xatolar uchun shaxsiy javobgarligini oshirish (bu erda biz pul jarimalari haqida emas, balki "g'oyani qabul qilish" haqida gapiramiz) haqida o'ylash kerak edi. avtomatik joylashtirish orqali vazifani qo'yib yuborish/bo'shatish emas. 

Sifat muammolarini bartaraf etib, biz ikkita muhim qarorga keldik: biz kanareyka sinovlarini o'tkazishni boshladik va xato fonini uning ortiqcha bo'lishiga avtomatik javob berish bilan avtomatik monitoringini joriy qildik. Birinchi yechim kod ishlab chiqarishga to'liq chiqarilishidan oldin aniq xatolarni topishga imkon berdi, ikkinchisi ishlab chiqarishdagi muammolarga javob berish vaqtini qisqartirdi. Xatolar, albatta, sodir bo'ladi, lekin biz ko'p vaqt va kuchimizni ularni tuzatishga emas, balki ularni kamaytirishga sarflaymiz. 

Avtomatlashtirish jamoasi

Hozirda bizda 130 ta dasturchi bor va biz davom etamiz o'sadi. Uzluksiz integratsiya va kod yetkazib berish bo'yicha guruh (keyingi o'rinlarda Deploy and Integration yoki DI jamoasi deb yuritiladi) 7 kishidan iborat bo'lib, 2 yo'nalishda ishlaydi: Integro avtomatlashtirish platformasini ishlab chiqish va DevOps. 

DevOps CIAN saytining Dev/Beta muhiti, Integro muhiti uchun mas'ul bo'lib, ishlab chiquvchilarga muammolarni hal qilishda yordam beradi va muhitlarni o'lchashga yangi yondashuvlarni ishlab chiqadi. Integroning rivojlanish yo'nalishi Integroning o'zi va tegishli xizmatlar bilan shug'ullanadi, masalan, Jenkins, Jira, Confluence uchun plaginlar, shuningdek, ishlab chiqish guruhlari uchun yordamchi yordamchi dasturlar va ilovalarni ishlab chiqadi. 

DI jamoasi arxitektura, kutubxonalar va rivojlanish yondashuvlarini ichki ishlab chiqadigan Platforma jamoasi bilan hamkorlikda ishlaydi. Shu bilan birga, CIAN ichidagi har qanday ishlab chiquvchi avtomatlashtirishga hissa qo'shishi mumkin, masalan, jamoaning ehtiyojlariga mos keladigan mikro-avtomatlashtirishni amalga oshirishi yoki avtomatlashtirishni yanada yaxshilash bo'yicha ajoyib g'oyani baham ko'rishi mumkin.

CIAN da avtomatlashtirishning qatlamli keki

Skriptlardan o'z platformamizgacha: biz CIAN-da rivojlanishni qanday avtomatlashtirdik

Avtomatlashtirish bilan bog'liq barcha tizimlarni bir necha qatlamlarga bo'lish mumkin:

  1. Tashqi tizimlar (Jira, Bitbucket va boshqalar). Rivojlanish guruhlari ular bilan ishlaydi.
  2. Integro platformasi. Ko'pincha, ishlab chiquvchilar u bilan to'g'ridan-to'g'ri ishlamaydilar, ammo bu barcha avtomatlashtirishning ishlashini ta'minlaydi.
  3. Yetkazib berish, orkestratsiya va kashfiyot xizmatlari (masalan, Jeknins, Konsul, Nomad). Ularning yordami bilan biz kodlarni serverlarga joylashtiramiz va xizmatlar bir-biri bilan ishlashini ta'minlaymiz.
  4. Jismoniy qatlam (serverlar, OS, tegishli dasturiy ta'minot). Bizning kodimiz shu darajada ishlaydi. Bu jismoniy yoki virtual server (LXC, KVM, Docker) bo'lishi mumkin.

Ushbu kontseptsiyaga asoslanib, biz DI jamoasi ichida mas'uliyat sohalarini ajratamiz. Birinchi ikki daraja Integro rivojlanish yo'nalishining javobgarligi sohasida, oxirgi ikki daraja esa DevOps mas'uliyati sohasida. Bu ajratish bizga vazifalarga e'tiborni qaratishga imkon beradi va o'zaro munosabatlarga xalaqit bermaydi, chunki biz bir-birimizga yaqinmiz va doimo bilim va tajriba almashamiz.

Buzilmagan

Keling, Integroga e'tibor qarataylik va texnologiya stekidan boshlaylik:

  • CentOS 7
  • Docker + Nomad + Konsul + Vault
  • Java 11 (eski Integro monolit Java 8 da qoladi)
  • Spring Boot 2.X + Spring Cloud Config
  • PostgreSql 11
  • Quyon MQ 
  • Apache Ignite
  • Camunda (o'rnatilgan)
  • Grafana + Grafit + Prometey + Jaeger + ELK
  • Veb UI: React (CSR) + MobX
  • SSO: Keyploak

Biz mikroservislarni ishlab chiqish tamoyiliga amal qilamiz, garchi bizda Integroning dastlabki versiyasining monoliti ko'rinishidagi meros mavjud. Har bir mikroservis o'zining Docker konteynerida ishlaydi va xizmatlar HTTP so'rovlari va RabbitMQ xabarlari orqali bir-biri bilan bog'lanadi. Mikroservislar konsul orqali bir-birini topadi va SSO (Keycloak, OAuth 2/OpenID Connect) orqali avtorizatsiyadan o'tib, unga so'rov yuboradi.

Skriptlardan o'z platformamizgacha: biz CIAN-da rivojlanishni qanday avtomatlashtirdik

Haqiqiy hayot misoli sifatida, quyidagi bosqichlardan iborat bo'lgan Jenkins bilan muloqot qilishni ko'rib chiqing:

  1. Ish oqimini boshqarish mikroservisi (keyingi o'rinlarda Flow mikroxizmati deb yuritiladi) Jenkins-da tuzilmani ishga tushirishni xohlaydi. Buning uchun u Jenkins (keyingi o'rinlarda Jenkins mikroservisi deb yuritiladi) bilan integratsiya qilish uchun mikroservisning IP: PORT manzilini topish uchun Konsuldan foydalanadi va unga Jenkinsda qurishni boshlash uchun asinxron so'rov yuboradi.
  2. So'rovni olgandan so'ng, Jenkins mikroservisi ish identifikatorini yaratadi va unga javob beradi, undan keyin ish natijasini aniqlash uchun foydalanish mumkin. Shu bilan birga, u REST API chaqiruvi orqali Jenkins-da qurilishni ishga tushiradi.
  3. Jenkins qurishni amalga oshiradi va tugallangandan so'ng, Jenkins mikroservisiga ijro natijalari bilan veb-huk yuboradi.
  4. Jenkins mikroservisi veb-hukni qabul qilib, so'rovni qayta ishlash tugaganligi haqida xabar ishlab chiqaradi va unga bajarish natijalarini biriktiradi. Yaratilgan xabar RabbitMQ navbatiga yuboriladi.
  5. RabbitMQ orqali chop etilgan xabar Flow mikroservisiga yetib boradi, u so'rov va qabul qilingan xabardagi Ish identifikatorini moslashtirish orqali o'z vazifasini qayta ishlash natijasi haqida bilib oladi.

Endi bizda 30 ga yaqin mikroservislar mavjud bo'lib, ularni bir necha guruhlarga bo'lish mumkin:

  1. Konfiguratsiyani boshqarish.
  2. Ma'lumot va foydalanuvchilar bilan o'zaro aloqa (messenjerlar, pochta).
  3. Manba kodi bilan ishlash.
  4. Joylashtirish vositalari bilan integratsiya (jenkins, ko'chmanchi, konsul va boshqalar).
  5. Monitoring (relizlar, xatolar va boshqalar).
  6. Veb-utilitalar (sinov muhitini boshqarish, statistik ma'lumotlarni yig'ish va boshqalar uchun UI).
  7. Vazifa izdoshlari va shunga o'xshash tizimlar bilan integratsiya.
  8. Turli vazifalar uchun ish oqimini boshqarish.

Ish jarayoni vazifalari

Integro vazifalarning hayot aylanishi bilan bog'liq faoliyatni avtomatlashtiradi. Soddalashtirilgan so'zlar bilan aytganda, vazifaning hayot aylanishi Jira'dagi vazifaning ish jarayoni sifatida tushuniladi. Bizning ishlab chiqish jarayonlarimiz loyihaga, vazifa turiga va ma'lum bir vazifada tanlangan variantlarga qarab bir nechta ish oqimining o'zgarishiga ega. 

Biz tez-tez ishlatadigan ish jarayonini ko'rib chiqaylik:

Skriptlardan o'z platformamizgacha: biz CIAN-da rivojlanishni qanday avtomatlashtirdik

Diagrammada vites o'tish Integro tomonidan avtomatik ravishda chaqirilishini ko'rsatadi, inson figurasi esa o'tish odam tomonidan qo'lda chaqirilishini bildiradi. Keling, ushbu ish jarayonida vazifa olishi mumkin bo'lgan bir nechta yo'llarni ko'rib chiqaylik.

DEV+BETA-da kanareyka sinovlarisiz to'liq qo'lda sinov (odatda biz monolitni shunday chiqaramiz):

Skriptlardan o'z platformamizgacha: biz CIAN-da rivojlanishni qanday avtomatlashtirdik

Boshqa o'tish kombinatsiyalari bo'lishi mumkin. Ba'zan muammoning yo'lini Jira'dagi variantlar orqali tanlash mumkin.

Vazifa harakati

Vazifa "DEV Testing + Canary Tests" ish jarayoni orqali o'tganda bajariladigan asosiy bosqichlarni ko'rib chiqaylik:

1. Ishlab chiquvchi yoki PM vazifani yaratadi.

2. Ishlab chiquvchi vazifani ishlash uchun oladi. Tugatgandan so'ng, u IN KO'RISH holatiga o'tadi.

3. Jira Jira mikroservisiga Webhook yuboradi (Jira bilan integratsiya uchun mas'ul).

4. Jira mikroservisi ish oqimini ishga tushirish uchun Flow xizmatiga (ish bajariladigan ichki ish oqimlari uchun mas'ul) so'rov yuboradi.

5. Flow xizmati ichida:

  • Taqrizchilar vazifaga tayinlangan (Foydalanuvchilar haqida hamma narsani biladigan mikroservis + Jira mikroservisi).
  • Manba mikroxizmati orqali (u omborlar va filiallar haqida biladi, lekin kodning o'zi bilan ishlamaydi) bizning masalamizning bo'limini o'z ichiga olgan omborlar uchun qidiruv amalga oshiriladi (qidirishni soddalashtirish uchun filialning nomi masala bilan mos keladi) Jiradagi raqam). Ko'pincha vazifa bitta omborda faqat bitta filialga ega; bu joylashtirish navbatini boshqarishni soddalashtiradi va omborlar orasidagi ulanishni kamaytiradi.
  • Har bir topilgan filial uchun quyidagi harakatlar ketma-ketligi bajariladi:

    i) Asosiy filialni yangilash (kod bilan ishlash uchun Git microservice).
    ii) Filial ishlab chiquvchi tomonidan o'zgarishlardan bloklangan (Bitbucket mikroservisi).
    iii) Ushbu filial uchun Pull so'rovi yaratilgan (Bitbucket mikroservisi).
    iv) Dasturchilar chatlariga yangi Pull so'rovi haqida xabar yuboriladi (Bildirishnomalar bilan ishlash uchun mikroservisga xabar bering).
    v) DEV (Jenkins bilan ishlash uchun Jenkins mikroservisi) da vazifalarni qurish, sinab ko'rish va joylashtirish boshlanadi.
    vi) Agar barcha oldingi qadamlar muvaffaqiyatli bajarilgan bo'lsa, Integro o'zining "Tasdiqlash" ni Pull Request (Bitbucket mikroxizmati) ga qo'yadi.

  • Integro tayinlangan sharhlovchilardan tortib olish so'rovida tasdiqlashni kutmoqda.
  • Barcha kerakli ruxsatnomalar (shu jumladan, avtomatlashtirilgan testlar ijobiy o‘tgan) olinsa, Integro vazifani Test on Dev (Jira microservice) holatiga o‘tkazadi.

6. Sinovchilar topshiriqni sinovdan o'tkazadilar. Hech qanday muammo bo'lmasa, vazifa Qurilishga tayyor holatiga o'tkaziladi.

7. Integro vazifani chiqarishga tayyorligini "ko'radi" va uni kanareyka rejimida (Jenkins mikroservisi) joylashtirishni boshlaydi. Chiqarishga tayyorlik bir qator qoidalar bilan belgilanadi. Masalan, vazifa kerakli holatda, boshqa vazifalarda hech qanday qulf yo'q, hozirda ushbu mikroservisning faol yuklamalari yo'q va hokazo.

8. Vazifa Canary holatiga o'tkaziladi (Jira mikroservisi).

9. Jenkins Nomad orqali kanareyka rejimida joylashtirish vazifasini ishga tushiradi (odatda 1-3 nusxada) va tarqatish monitoringi xizmatini (DeployWatch microservice) tarqatish haqida xabardor qiladi.

10. DeployWatch mikroservisi xato fonini to'playdi va agar kerak bo'lsa, unga munosabat bildiradi. Agar xato foni oshib ketgan bo'lsa (fon normasi avtomatik ravishda hisoblab chiqiladi), ishlab chiquvchilar Notify mikroservisi orqali xabardor qilinadi. Agar 5 daqiqadan so'ng ishlab chiquvchi javob bermasa (Qayta tiklash yoki Qolib ketish tugmasini bosgan holda), kanareyka nusxalarini avtomatik ravishda qaytarish ishga tushiriladi. Agar fon o'tilmagan bo'lsa, ishlab chiquvchi ishlab chiqarishga topshiriqni qo'llashni qo'lda ishga tushirishi kerak (UIdagi tugmani bosish orqali). Agar 60 daqiqa ichida ishlab chiquvchi ishlab chiqarishga joylashtirishni boshlamagan bo'lsa, xavfsizlik sababli kanareykalar ham orqaga qaytariladi.

11. Ishlab chiqarishga joylashtirishni ishga tushirgandan so'ng:

  • Vazifa ishlab chiqarish holatiga o'tkaziladi (Jira mikroservisi).
  • Jenkins mikroxizmati o'rnatish jarayonini boshlaydi va DeployWatch mikroservisni tarqatish haqida xabardor qiladi.
  • DeployWatch mikroservisi ishlab chiqarishdagi barcha konteynerlar yangilanganligini tekshiradi (barchasi yangilanmagan holatlar ham bo'lgan).
  • Notify mikroxizmati orqali ishlab chiqarishga joylashtirish natijalari haqida bildirishnoma yuboriladi.

12. Mikroservisning noto'g'ri xatti-harakati aniqlansa, ishlab chiquvchilarga ishlab chiqarishdan topshiriqni qaytarishni boshlash uchun 30 daqiqa vaqt beriladi. Bu vaqtdan keyin vazifa avtomatik ravishda master (Git microservice) bilan birlashtiriladi.

13. Magistrga muvaffaqiyatli birlashtirilgandan so'ng, vazifa holati Yopiq (Jira mikroservisi) ga o'zgartiriladi.

Diagramma o'zini to'liq batafsil ko'rsatmaydi (aslida bundan ham ko'proq qadamlar mavjud), ammo u jarayonlarga integratsiya darajasini baholashga imkon beradi. Biz ushbu sxemani ideal deb hisoblamaymiz va avtomatik chiqarish va joylashtirishni qo'llab-quvvatlash jarayonlarini takomillashtirmoqdamiz.

Keyin nima

Bizda avtomatlashtirishni rivojlantirish bo'yicha katta rejalarimiz bor, masalan, monolitlarni chiqarish paytida qo'lda operatsiyalarni bartaraf etish, avtomatik joylashtirish paytida monitoringni yaxshilash va ishlab chiquvchilar bilan o'zaro aloqani yaxshilash.

Ammo hozircha shu erda to'xtab qolaylik. Biz avtomatlashtirishni ko'rib chiqishda ko'plab mavzularni yuzaki yoritib berdik, ba'zilariga umuman tegilmagan, shuning uchun biz savollarga javob berishdan mamnun bo'lamiz. Biz nimani batafsil yoritish bo'yicha takliflarni kutamiz, izohlarda yozing.

Manba: www.habr.com

a Izoh qo'shish