{"id":55870,"date":"2020-01-30T00:00:00","date_gmt":"2020-01-29T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/ot-skriptov-k-sobstvennoj-platforme-kak-my-avtomatizirovali-razrabotku-v-tsian"},"modified":"2020-02-18T14:04:02","modified_gmt":"2020-02-18T11:04:02","slug":"ot-skriptov-k-sobstvennoj-platforme-kak-my-avtomatizirovali-razrabotku-v-tsian","status":"publish","type":"post","link":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/ot-skriptov-k-sobstvennoj-platforme-kak-my-avtomatizirovali-razrabotku-v-tsian","title":{"rendered":"De la scripturi la propria platform\u0103: cum am automatizat dezvoltarea \u00een CIAN","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"De la scripturi la propria platform\u0103: cum am automatizat dezvoltarea \u00een CIAN\" src=\"\/wp-content\/uploads\/2020\/01\/965f1944c95e2020bec512a05d980a32.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLa RIT 2019, colegul nostru Alexandr Korotkov a discutat <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=0wvUyjexoIg\">raport<\/a><\/noindex> despre automatizarea dezvolt\u0103rii la CIAN: pentru a simplifica via\u021ba \u0219i munca, folosim propria noastr\u0103 platform\u0103 Integro. Aceasta urm\u0103re\u0219te ciclul de via\u021b\u0103 al sarcinilor, \u00eendep\u0103rteaz\u0103 sarcinile repetitive de la dezvoltatori \u0219i reduce semnificativ num\u0103rul de bug-uri \u00een produc\u021bie. \u00cen aceast\u0103 postare, vom completa prezentarea lui Alexandr \u0219i vom \u00eemp\u0103rt\u0103\u0219i cum am evoluat de la scripturi simple la integrarea produselor open source prin propria noastr\u0103 platform\u0103 \u0219i cu ce se ocup\u0103 o echip\u0103 separat\u0103 de automatizare.<br \/>\n\u00a0<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Nivelul zero<\/h2>\n<p>\n<i><b>\u201eNu exist\u0103 nivel zero, nu \u0219tiu a\u0219a ceva\u201d<\/b><br \/>\nMister Shifu din m\/f \u201eKung Fu Panda\u201d<\/i><\/p>\n<p>Automatizarea la CIAN a \u00eenceput la 14 ani dup\u0103 \u00eenfiin\u021barea companiei. Atunci, echipa de dezvoltare num\u0103ra 35 de persoane. E greu de crezut, nu? Desigur, \u00eentr-o form\u0103 oarecare, automatizarea exista, dar un domeniu separat pentru integrarea continu\u0103 \u0219i livrarea codului a \u00eenceput s\u0103 se contureze exact \u00een anul 2015.\u00a0<\/p>\n<p>La acel moment, aveam un monolit uria\u0219 din Python, C# \u0219i PHP, desf\u0103\u0219urat pe servere Linux\/Windows. Pentru a desf\u0103\u0219ura acest monstru, aveam un set de scripturi pe care le rulam manual. Mai exista \u0219i construc\u021bia monolitului, care provoca dureri \u0219i suferin\u021be din cauza conflictelor la unirea ramurilor, corect\u0103rii defectelor \u0219i reconstruc\u0103rii \u201ecu un alt set de sarcini \u00een build\u201d. Simplificat, procesul ar\u0103ta astfel:<\/p>\n<p><img decoding=\"async\" alt=\"De la scripturi la propria platform\u0103: cum am automatizat dezvoltarea \u00een CIAN\" src=\"\/wp-content\/uploads\/2020\/01\/03c4dd97e2ba0073bab1c33f6003a9ec.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNu eram mul\u021bumi\u021bi de asta \u0219i voiam s\u0103 construim un proces de construc\u021bie \u0219i desf\u0103\u0219urare repetabil, automatizat \u0219i gestionat. Pentru aceasta, aveam nevoie de un sistem CI\/CD, \u0219i am ales \u00eentre versiunea gratuit\u0103 Teamcity \u0219i Jenkins gratuit, deoarece lucrasem cu ambele \u0219i ne satisf\u0103ceau prin setul de func\u021bii. Am ales Teamcity ca produs mai nou. Atunci nu foloseam arhitectur\u0103 de microservicii \u0219i nu ne a\u0219teptam la un num\u0103r mare de sarcini \u0219i proiecte.<\/p>\n<h2>Ajungem la ideea despre propriul sistem<\/h2>\n<p>\nImplementarea Teamcity a redus doar o parte din munca manual\u0103: a r\u0103mas \u00eenc\u0103 necesar s\u0103 se creeze Pull Request-uri, s\u0103 se promoveze sarcinile prin statusuri \u00een Jira, s\u0103 se aleag\u0103 sarcinile pentru lansare. Cu acest lucru, sistemul Teamcity nu mai reu\u0219ea. Trebuia s\u0103 alegem calea unei automatiz\u0103ri suplimentare. Am luat \u00een considerare op\u021biuni de lucru cu scripturi \u00een Teamcity sau tranzi\u021bia la sisteme externe de automatizare. Dar, \u00een cele din urm\u0103, am decis c\u0103 avem nevoie de cea mai mare flexibilitate, pe care o ofer\u0103 doar o solu\u021bie proprie. A\u0219a a ap\u0103rut prima versiune a sistemului nostru intern de automatizare numit Integro.<\/p>\n<p>Teamcity se ocup\u0103 cu automatizarea la nivelul lans\u0103rii proceselor de construire \u0219i implementare, \u00een timp ce Integro s-a concentrat pe automatizarea la un nivel superior a proceselor de dezvoltare. A fost necesar s\u0103 combin\u0103m lucrul cu sarcinile din Jira cu procesarea codului surs\u0103 asociat \u00een Bitbucket. \u00cen acest stadiu, \u00een interiorul Integro au \u00eenceput s\u0103 apar\u0103 fluxuri de lucru proprii pentru gestionarea sarcinilor de diferite tipuri.\u00a0<\/p>\n<p>Datorit\u0103 cre\u0219terii automatiz\u0103rii \u00een procesele de business, num\u0103rul de proiecte \u0219i run-uri \u00een Teamcity a crescut. A\u0219a a ap\u0103rut o nou\u0103 problem\u0103: un singur instan\u021b gratuit de Teamcity nu mai era suficient (3 agen\u021bi \u0219i 100 de proiecte), am ad\u0103ugat \u00eenc\u0103 un instan\u021b (\u00eenc\u0103 3 agen\u021bi \u0219i 100 de proiecte), apoi \u00eenc\u0103 unul. \u00cen final, am ob\u021binut un sistem format din mai multe clustere, pe care era dificil s\u0103 \u00eel gestion\u0103m:<\/p>\n<p><img decoding=\"async\" alt=\"De la scripturi la propria platform\u0103: cum am automatizat dezvoltarea \u00een CIAN\" src=\"\/wp-content\/uploads\/2020\/01\/d95565e01e70e31f6b139dfb9b9caf95.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nC\u00e2nd a ap\u0103rut \u00eentrebarea despre al patrulea instan\u021b, am realizat c\u0103 nu mai putem continua astfel, deoarece costurile totale pentru sus\u021binerea a patru instan\u021be dep\u0103\u0219eau orice limit\u0103. A ap\u0103rut \u00eentrebarea achizi\u021bion\u0103rii unui Teamcity pl\u0103tit sau alegerea unei solu\u021bii gratuite Jenkins. Am realizat calculele pentru instan\u021be \u0219i planurile de automatizare \u0219i am decis c\u0103 vom continua pe Jenkins. Dup\u0103 c\u00e2teva s\u0103pt\u0103m\u00e2ni, am trecut pe Jenkins \u0219i ne-am eliberat de o parte din durerea de cap legat\u0103 de gestionarea mai multor instan\u021be Teamcity. A\u0219adar, am putut s\u0103 ne concentr\u0103m pe dezvoltarea Integro \u0219i adaptarea Jenkins pentru nevoile noastre.<\/p>\n<p>Odat\u0103 cu cre\u0219terea automatiz\u0103rii de baz\u0103 (sub forma cre\u0103rii automate de Pull Request-uri, colect\u0103rii \u0219i public\u0103rii acoperirii codului \u0219i altor verific\u0103ri) a ap\u0103rut o dorin\u021b\u0103 persistent\u0103 de a renun\u021ba la lans\u0103rile manuale \u0219i de a l\u0103sa aceast\u0103 munc\u0103 robo\u021bilor. Pe l\u00e2ng\u0103 asta, \u00een interiorul companiei a \u00eenceput o migrare c\u0103tre microservicii, care necesitau lans\u0103ri frecvente, separate unele de altele. Astfel, am ajuns treptat la lans\u0103ri automate ale microserviciilor noastre (monolitul este \u00eenc\u0103 lansat manual din cauza complexit\u0103\u021bii procesului). Dar, a\u0219a cum se \u00eent\u00e2mpl\u0103 de obicei, a ap\u0103rut o nou\u0103 dificultate.\u00a0<\/p>\n<h2>Automatiz\u0103m testarea<\/h2>\n<p>\n<img decoding=\"async\" alt=\"De la scripturi la propria platform\u0103: cum am automatizat dezvoltarea \u00een CIAN\" src=\"\/wp-content\/uploads\/2020\/01\/9518ee0956922c6eb615bdef068ac525.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDatorit\u0103 automatiz\u0103rii lans\u0103rilor, procesele de dezvoltare s-au accelerat, par\u021bial \u0219i prin omisiunea unor etape de testare. Iar aceasta a dus la o pierdere temporar\u0103 a calit\u0103\u021bii. Sun\u0103 banal, dar \u00eempreun\u0103 cu accelerarea lans\u0103rilor, a fost necesar s\u0103 schimb\u0103m \u0219i metodologia de dezvoltare a produsului. A fost nevoie s\u0103 ne g\u00e2ndim la automatizarea test\u0103rii, la promovarea responsabilit\u0103\u021bii personale (aici se vorbe\u0219te despre \"asumarea ideii \u00een minte\", nu despre amenzi financiare) a dezvoltatorului pentru codul livrat \u0219i erorile din acesta, precum \u0219i la o decizie privind livrarea\/nerularea sarcinii prin intermediul unui deploy automatizat.\u00a0<\/p>\n<p>Elimin\u00e2nd problemele legate de calitate, am ajuns la dou\u0103 solu\u021bii importante: am \u00eenceput s\u0103 desf\u0103\u0219ur\u0103m teste canarie \u0219i am implementat monitorizarea automat\u0103 a erorilor cu reac\u021bie automat\u0103 la dep\u0103\u0219irea acestora. Prima solu\u021bie a permis identificarea erorilor evidente \u00eenainte de a ajunge codul \u00een produc\u021bie, iar a doua a redus timpul de reac\u021bie la problemele din produc\u021bie. Erorile, desigur, exist\u0103, dar cheltuim mai mult timp \u0219i efort nu pe corectare, ci pe minimizare.\u00a0<\/p>\n<h2>Echipa de automatizare<\/h2>\n<p>\n\u00cen prezent, avem un personal de 130 de dezvoltatori \u0219i continu\u0103m <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/article\/469965\/\">s\u0103 cre\u0219tem<\/a><\/noindex>. Echipa de integrare \u0219i livrare continu\u0103 a codului (\u00een continuare \u2013 echipa Deploy and Integration sau DI) este format\u0103 din 7 persoane \u0219i lucreaz\u0103 \u00een 2 direc\u021bii: dezvoltarea platformei de automatizare Integro \u0219i DevOps.\u00a0<\/p>\n<p>DevOps este responsabil pentru mediile Dev\/Beta ale site-ului CIAN, pentru mediu Integro, ajut\u00e2nd dezvoltatorii s\u0103 rezolve probleme \u0219i dezvolt\u00e2nd noi abord\u0103ri pentru scalarea mediilor. Direc\u021bia de dezvoltare Integro se ocup\u0103 at\u00e2t de Integro \u00een sine, c\u00e2t \u0219i de servicii conexe, cum ar fi pluginuri pentru Jenkins, Jira, Confluence, precum \u0219i dezvoltarea de utilitare \u0219i aplica\u021bii auxiliare pentru echipele de dezvoltare.\u00a0<\/p>\n<p>Echipa DI colaboreaz\u0103 cu echipa Platformei, care se ocup\u0103 de dezvoltarea arhitecturii, bibliotecilor \u0219i abord\u0103rilor de dezvoltare \u00een cadrul companiei. \u00cen plus, orice dezvoltator din cadrul CIAN poate contribui la automatizare, de exemplu, realiz\u00e2nd micro-automatiz\u0103ri pentru nevoile echipei sau \u00eemp\u0103rt\u0103\u0219ind idei interesante pentru a \u00eembun\u0103t\u0103\u021bi automatizarea.<\/p>\n<h2>Pachetul stratificat de automatizare la CIAN<\/h2>\n<p>\n<img decoding=\"async\" alt=\"De la scripturi la propria platform\u0103: cum am automatizat dezvoltarea \u00een CIAN\" src=\"\/wp-content\/uploads\/2020\/01\/22dcd2d0cc283d53bdaac081885657f8.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nToate sistemele implicate \u00een automatizare pot fi \u00eemp\u0103r\u021bite \u00een mai multe straturi:<\/p>\n<ol>\n<li>Sisteme externe (Jira, Bitbucket etc.). Acestea sunt utilizate de echipele de dezvoltare.\n<\/li>\n<li>Platforma Integro. Cel mai adesea dezvoltatorii nu interac\u021bioneaz\u0103 direct cu aceasta, dar ea sus\u021bine func\u021bionarea \u00eentregii automatiz\u0103ri.\n<\/li>\n<li>Servicii de livrare, orchestrare \u0219i detectare (cum ar fi Jenkins, Consul, Nomad). Cu ajutorul lor desf\u0103\u0219ur\u0103m codul pe servere \u0219i asigur\u0103m comunicarea serviciilor \u00eentre ele.\n<\/li>\n<li>Nivelul fizic (servere, SO, software conex). Pe acest nivel ruleaz\u0103 codul nostru. Poate fi at\u00e2t un server fizic, c\u00e2t \u0219i unul virtual (LXC, KVM, Docker).\n<\/li>\n<\/ol>\n<p>\nPe baza acestei concep\u021bii, \u00eemp\u0103r\u021bim zonele de responsabilitate \u00een cadrul echipei DI. Primele dou\u0103 niveluri se afl\u0103 \u00een responsabilitatea direc\u021biei de dezvoltare Integro, iar ultimele dou\u0103 \u00een responsabilitatea DevOps. Aceast\u0103 \u00eemp\u0103r\u021bire permite concentrarea asupra sarcinilor \u0219i nu \u00eempiedic\u0103 interac\u021biunea, deoarece suntem aproape unul de cel\u0103lalt \u0219i schimb\u0103m constant cuno\u0219tin\u021be \u0219i experien\u021be.<\/p>\n<h2>Integro<\/h2>\n<p>\nS\u0103 ne concentr\u0103m asupra Integro \u0219i s\u0103 \u00eencepem cu tehnologia utilizat\u0103:<\/p>\n<ul>\n<li>CentOs 7\n<\/li>\n<li>Docker + Nomad + Consul + Vault\n<\/li>\n<li>Java 11 (monolitul vechi Integro va r\u0103m\u00e2ne pe Java 8)\n<\/li>\n<li>Spring Boot 2.X + Spring Cloud Config\n<\/li>\n<li>PostgreSql 11\n<\/li>\n<li>RabbitMQ\u00a0\n<\/li>\n<li>Apache Ignite\n<\/li>\n<li>Camunda (\u00eencorporat)\n<\/li>\n<li>Grafana + Graphite + Prometheus + Jaeger + ELK\n<\/li>\n<li>Interfa\u021b\u0103 Web: React (CSR) + MobX\n<\/li>\n<li>SSO: Keycloak\n<\/li>\n<\/ul>\n<p>\nRespect\u0103m principiul dezvolt\u0103rii microserviciilor, de\u0219i avem \u0219i un legacy sub form\u0103 de monolit din versiunea timpurie a Integro. Fiecare microserviciu ruleaz\u0103 \u00een propriul s\u0103u container Docker, iar serviciile comunic\u0103 \u00eentre ele prin solicit\u0103ri HTTP \u0219i mesaje RabbitMQ. Microserviciile se g\u0103sesc reciproc prin Consul \u0219i \u00eei fac solicit\u0103ri, trec\u00e2nd prin autentificare prin SSO (Keycloak, OAuth 2\/OpenID Connect).<\/p>\n<p><img decoding=\"async\" alt=\"De la scripturi la propria platform\u0103: cum am automatizat dezvoltarea \u00een CIAN\" src=\"\/wp-content\/uploads\/2020\/01\/e7630c0bd62a40f397de1bf1c1097926.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCa exemplu concret, s\u0103 lu\u0103m interac\u021biunea cu Jenkins, care const\u0103 din urm\u0103torii pa\u0219i:<\/p>\n<ol>\n<li>Microserviciul de gestionare a fluxului de lucru (denumit \u00een continuare microserviciul Flow) vrea s\u0103 ini\u021bieze o construc\u021bie \u00een Jenkins. Pentru aceasta, g\u0103se\u0219te prin Consul IP:PORT-ul microserviciului de integrare cu Jenkins (denumit \u00een continuare microserviciul Jenkins) \u0219i \u00eei trimite o solicitare asincron\u0103 pentru a lansa construc\u021bia \u00een Jenkins.\n<\/li>\n<li>Microserviciul Jenkins, dup\u0103 primirea solicit\u0103rii, formeaz\u0103 \u0219i trimite \u00eenapoi un ID de job, prin care va putea fi identificat ulterior rezultatul execu\u021biei. \u00cempreun\u0103 cu aceasta, ini\u021biaz\u0103 construc\u021bia \u00een Jenkins prin apelul API REST.\n<\/li>\n<li>Jenkins execut\u0103 construc\u021bia \u0219i, la finalizarea acesteia, trimite un webhook cu rezultatele execu\u021biei c\u0103tre microserviciul Jenkins.\n<\/li>\n<li>Microserviciul Jenkins, primind webhook-ul, formeaz\u0103 un mesaj de finalizare a proces\u0103rii solicit\u0103rii \u0219i ata\u0219eaz\u0103 rezultatele execu\u021biei. Mesajul format este trimis \u00een coada RabbitMQ.\n<\/li>\n<li>Prin RabbitMQ, mesajul publicat ajunge la microserviciul Flow, care afl\u0103 despre rezultatul proces\u0103rii sarcinii sale, corel\u00e2nd ID-ul job-ului din solicitare cu mesajul primit.\n<\/li>\n<\/ol>\n<p>\nAcum avem aproximativ 30 de microservicii, care pot fi \u00eemp\u0103r\u021bite \u00een mai multe grupuri:<\/p>\n<ol>\n<li>Gestionarea configura\u021biilor.\n<\/li>\n<li>Informarea \u0219i interac\u021biunea cu utilizatorii (messenger, email).\n<\/li>\n<li>Lucrul cu codul surs\u0103.\n<\/li>\n<li>Integrarea cu instrumentele de deploy (Jenkins, Nomad, Consul etc.).\n<\/li>\n<li>Monitorizare (lans\u0103ri, erori etc.).\n<\/li>\n<li>Utilitare web (UI pentru gestionarea mediilor de testare, colectarea statisticilor etc.).\n<\/li>\n<li>Integrarea cu sisteme de urm\u0103rire a sarcinilor \u0219i similare.\n<\/li>\n<li>Gestionarea fluxului de lucru pentru diferite sarcini.\n<\/li>\n<\/ol>\n<p><\/p>\n<h2>Fluxul de lucru al sarcinii<\/h2>\n<p>\nIntegro automatizeaz\u0103 ac\u021biunile legate de ciclul de via\u021b\u0103 al unei sarcini. Simplificat, vom \u00een\u021belege prin ciclul de via\u021b\u0103 al unei sarcini fluxul de lucru al sarcinii \u00een Jira. \u00cen procesele noastre de dezvoltare exist\u0103 c\u00e2teva varia\u021bii de flux de lucru \u00een func\u021bie de proiect, tipul sarcinii \u0219i op\u021biunile alese \u00een cadrul sarcinii specifice.\u00a0<\/p>\n<p>S\u0103 analiz\u0103m fluxul de lucru pe care \u00eel folosim cel mai des:<\/p>\n<p><img decoding=\"async\" alt=\"De la scripturi la propria platform\u0103: cum am automatizat dezvoltarea \u00een CIAN\" src=\"\/wp-content\/uploads\/2020\/01\/62555be6bab024dd30f3cf70d4fe3cba.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00cen schem\u0103, roti\u021ba indic\u0103 faptul c\u0103 transition este apelat automat de Integro, \u00een timp ce figurina omului \u00eenseamn\u0103 c\u0103 transition este ini\u021biat manual de o persoan\u0103. S\u0103 lu\u0103m \u00een considerare c\u00e2teva c\u0103i prin care sarcina poate trece \u00een acest workflow.<\/p>\n<p>Testare complet manual\u0103 pe DEV+BETA f\u0103r\u0103 teste canar (de obicei, a\u0219a lans\u0103m monolitul):<\/p>\n<p><img decoding=\"async\" alt=\"De la scripturi la propria platform\u0103: cum am automatizat dezvoltarea \u00een CIAN\" src=\"\/wp-content\/uploads\/2020\/01\/775528862e14817dff5f69db6de654dd.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPot exista \u0219i alte combina\u021bii de transition. Uneori, calea pe care o va urma sarcina poate fi aleas\u0103 prin op\u021biuni \u00een Jira.<\/p>\n<h2>Mi\u0219carea sarcinii<\/h2>\n<p>\nS\u0103 lu\u0103m \u00een considerare pa\u0219ii principali care sunt realiza\u021bi \u00een timpul mi\u0219c\u0103rii sarcinii prin workflow-ul \u201eTestare pe DEV + teste canar\u201d:<\/p>\n<p>1. Dezvoltatorul sau PM-ul creeaz\u0103 o sarcin\u0103.<\/p>\n<p>2. Dezvoltatorul preia sarcina. Dup\u0103 finalizare, o trimite \u00een statusul IN REVIEW.<\/p>\n<p>3. Jira trimite un Webhook c\u0103tre microserviciul Jira (responsabil cu integrarea cu Jira).<\/p>\n<p>4. Microserviciul Jira trimite o cerere c\u0103tre serviciul Flow (responsabil cu workflow-urile interne, \u00een care se desf\u0103\u0219oar\u0103 activitatea) pentru a lansa workflow-ul.<\/p>\n<p>5. \u00cen interiorul serviciului Flow:<\/p>\n<ul>\n<li>Se desemneaz\u0103 revizorii pentru sarcin\u0103 (microserviciul Users, care \u0219tie tot despre utilizatori, + microserviciul Jira).<\/li>\n<li>Prin microserviciul Source (cunoa\u0219te despre repo-uri \u0219i ramuri, dar nu lucreaz\u0103 cu codul \u00een sine) se caut\u0103 repo-uri \u00een care exist\u0103 o ramur\u0103 a sarcinii noastre (pentru a simplifica c\u0103utarea, numele ramurii coincide cu num\u0103rul sarcinii din Jira). Cel mai adesea, sarcina are doar o ramur\u0103 \u00eentr-un singur repo, ceea ce simplific\u0103 gestionarea cozii pentru deploy \u0219i reduce leg\u0103tura dintre repo-uri.<\/li>\n<li>Pentru fiecare ramur\u0103 g\u0103sit\u0103 se execut\u0103 o astfel de secven\u021b\u0103 de ac\u021biuni:\n<p> i) \u00cencorporarea ramurii master (microserviciul Git pentru a lucra cu codul).<br \/>\n ii) Ramura este blocat\u0103 de modific\u0103ri de c\u0103tre dezvoltator (microserviciul Bitbucket).<br \/>\n iii) Se creeaz\u0103 un Pull Request pentru aceast\u0103 ramur\u0103 (microserviciul Bitbucket).<br \/>\n iv) Se trimite un mesaj despre noul Pull Request \u00een chat-urile dezvoltatorilor (microserviciul Notify pentru a lucra cu notific\u0103rile).<br \/>\n v) Se lanseaz\u0103 compilarea, testarea \u0219i deploy-ul sarcinii pe DEV (microserviciul Jenkins pentru a lucra cu Jenkins).<br \/>\n vi) Dac\u0103 toate punctele anterioare s-au \u00eencheiat cu succes, Integro \u00ee\u0219i pune aprovarea \u00een Pull Request (microserviciul Bitbucket).<\/li>\n<li>Integro a\u0219teapt\u0103 aprobatul \u00een Pull Request de la revizorii desemna\u021bi.<\/li>\n<li>Odat\u0103 ce au fost primite toate aprob\u0103rile necesare (inclusiv testele automatizate trecute pozitiv), Integro trimite sarcina \u00een statusul Test on Dev (microserviciul Jira).<\/li>\n<\/ul>\n<p>\n6. Testeri efectueaz\u0103 testarea sarcinii. Dac\u0103 nu sunt probleme, atunci transfer\u0103 sarcina \u00een statutul Ready For Build.<\/p>\n<p>7. Integro \u201evede\u201d c\u0103 sarcina este gata de lansare \u0219i ini\u021biaz\u0103 desf\u0103\u0219urarea acesteia \u00een modul canary (microserviciul Jenkins). Preg\u0103tirea pentru lansare este determinat\u0103 de un set de reguli. De exemplu, sarcina trebuie s\u0103 fie \u00een statutul corect, f\u0103r\u0103 blocaje pe alte sarcini, iar \u00een prezent nu trebuie s\u0103 existe desf\u0103\u0219ur\u0103ri active ale acestui microserviciu etc.<\/p>\n<p>8. Sarcina este transferat\u0103 \u00een statutul Canary (microserviciul Jira).<\/p>\n<p>9. Jenkins ini\u021biaz\u0103 desf\u0103\u0219urarea sarcinii prin Nomad \u00een modul canary (de obicei 1-3 instan\u021be) \u0219i notific\u0103 serviciul de monitorizare a desf\u0103\u0219ur\u0103rilor (microserviciul DeployWatch).<\/p>\n<p>10. Microserviciul DeployWatch colecteaz\u0103 fondul de erori \u0219i reac\u021bioneaz\u0103 la acesta, dac\u0103 este necesar. Dac\u0103 fondul de erori dep\u0103\u0219e\u0219te norma (care este calculat\u0103 automat), dezvoltatorii sunt notifica\u021bi prin microserviciul Notify. Dac\u0103 dup\u0103 5 minute dezvoltatorul nu a reac\u021bionat (a ap\u0103sat Revert sau Stay), atunci ini\u021biaz\u0103 o revenire automat\u0103 a instan\u021belor canary. Dac\u0103 fondul nu este dep\u0103\u0219it, dezvoltatorul trebuie s\u0103 ini\u021bieze manual desf\u0103\u0219urarea sarcinii \u00een Production (ap\u0103s\u00e2nd un buton \u00een UI). Dac\u0103 \u00een termen de 60 de minute dezvoltatorul nu a ini\u021biat desf\u0103\u0219urarea \u00een Production, instan\u021bele canary vor fi, de asemenea, retrase din motive de securitate.<\/p>\n<p>11. Dup\u0103 ini\u021bierea desf\u0103\u0219ur\u0103rii \u00een Production:<\/p>\n<ul>\n<li>Sarcina este transferat\u0103 \u00een statutul Production (microserviciul Jira).<\/li>\n<li>Microserviciul Jenkins ini\u021biaz\u0103 procesul de desf\u0103\u0219urare \u0219i notific\u0103 despre desf\u0103\u0219urare microserviciul DeployWatch.<\/li>\n<li>Microserviciul DeployWatch verific\u0103 c\u0103 toate containerele din Production au fost actualizate (au existat cazuri \u00een care nu toate au fost actualizate).<\/li>\n<li>Prin microserviciul Notify se trimite o notificare referitoare la rezultatele desf\u0103\u0219ur\u0103rii \u00een Production.<\/li>\n<\/ul>\n<p>\n12. Dezvoltatorii vor avea 30 de minute pentru a ini\u021bia revenirea sarcinii din Production \u00een cazul \u00een care se descoper\u0103 un comportament incorect al microserviciului. La expirarea acestui timp, sarcina va fi integrat\u0103 automat \u00een master (microserviciul Git).<\/p>\n<p>13. Dup\u0103 un merge reu\u0219it \u00een master, statutul sarcinii va fi modificat \u00een Closed (microserviciul Jira).<\/p>\n<p>Schema nu pretinde a fi complet detaliat\u0103 (de fapt, sunt mai multe etape), dar permite evaluarea gradului de integrare \u00een procese. Nu consider\u0103m c\u0103 aceast\u0103 schem\u0103 este ideal\u0103 \u0219i \u00eembun\u0103t\u0103\u021bim procesele de asisten\u021b\u0103 automat\u0103 pentru desf\u0103\u0219ur\u0103ri \u0219i desf\u0103\u0219ur\u0103ri.<\/p>\n<h2>Ce urmeaz\u0103<\/h2>\n<p>\nAvem planuri mari pentru dezvoltarea automatiz\u0103rii, cum ar fi renun\u021barea la opera\u021biunile manuale la lans\u0103rile monolitului, \u00eembun\u0103t\u0103\u021birea monitoriz\u0103rii \u00een timpul desf\u0103\u0219ur\u0103rii automate, \u00eembun\u0103t\u0103\u021birea colabor\u0103rii cu dezvoltatorii.<\/p>\n<p>Dar ne oprim aici pentru acum. Am atins multe subiecte \u00een revizuirea automatiz\u0103rii la o scar\u0103 superficial\u0103, iar unele nu le-am abordat deloc, a\u0219a c\u0103 suntem bucuro\u0219i s\u0103 r\u0103spundem la \u00eentreb\u0103ri. A\u0219tept\u0103m sugestii despre ce s\u0103 detaliem, scrie\u021bi \u00een comentarii.<br \/>\n<br \/>Sursa: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/cian\/blog\/486056\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041d\u0430 \u0420\u0418\u0422 2019 \u043d\u0430\u0448 \u043a\u043e\u043b\u043b\u0435\u0433\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u041a\u043e\u0440\u043e\u0442\u043a\u043e\u0432 \u0441\u0434\u0435\u043b\u0430\u043b \u0434\u043e\u043a\u043b\u0430\u0434 \u043f\u0440\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432 \u0426\u0418\u0410\u041d: \u0447\u0442\u043e\u0431\u044b \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0436\u0438\u0437\u043d\u044c \u0438 \u0440\u0430\u0431\u043e\u0442\u0443, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443 Integro. \u041e\u043d\u0430 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0437\u0430\u0434\u0430\u0447, \u0441\u043d\u0438\u043c\u0430\u0435\u0442 \u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0440\u0443\u0442\u0438\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u0437\u0430\u043c\u0435\u0442\u043d\u043e \u0441\u043e\u043a\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0430\u0433\u043e\u0432 \u0432 production. \u0412 \u044d\u0442\u043e\u043c \u043f\u043e\u0441\u0442\u0435 \u043c\u044b \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u043c \u0434\u043e\u043a\u043b\u0430\u0434 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0438 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u043f\u0440\u043e\u0448\u043b\u0438 \u043f\u0443\u0442\u044c \u043e\u0442 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-55870","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041d\u0430 \u0420\u0418\u0422 2019.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/ot-skriptov-k-sobstvennoj-platforme-kak-my-avtomatizirovali-razrabotku-v-tsian\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041e\u0442 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u043a \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435: \u043a\u0430\u043a \u043c\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0432 \u0426\u0418\u0410\u041d | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041d\u0430 \u0420\u0418\u0422 2019.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/ot-skriptov-k-sobstvennoj-platforme-kak-my-avtomatizirovali-razrabotku-v-tsian\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-01-29T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:04:02+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47De la scripturi la propria platform\u0103: cum am automatizat dezvoltarea la CIAN | ProHoster","description":"La RIT 2019.","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/ot-skriptov-k-sobstvennoj-platforme-kak-my-avtomatizirovali-razrabotku-v-tsian","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041e\u0442 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u043a \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435: \u043a\u0430\u043a \u043c\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0432 \u0426\u0418\u0410\u041d | ProHoster","og:description":"\u041d\u0430 \u0420\u0418\u0422 2019.","og:url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/ot-skriptov-k-sobstvennoj-platforme-kak-my-avtomatizirovali-razrabotku-v-tsian","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-01-29T21:00:00+00:00","article:modified_time":"2020-02-18T11:04:02+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"55870","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:35:40","updated":"2022-09-30 17:42:13","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/55870","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=55870"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/55870\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=55870"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=55870"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=55870"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}