{"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\/pl\/blog\/administrirovanie\/ot-skriptov-k-sobstvennoj-platforme-kak-my-avtomatizirovali-razrabotku-v-tsian","title":{"rendered":"Od skrypt\u00f3w do w\u0142asnej platformy: jak zautomatyzowali\u015bmy rozw\u00f3j w CIAN","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Od skrypt\u00f3w do w\u0142asnej platformy: jak zautomatyzowali\u015bmy rozw\u00f3j w CIAN\" src=\"\/wp-content\/uploads\/2020\/01\/965f1944c95e2020bec512a05d980a32.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNa RIT 2019 nasz kolega Aleksandr Korotkow wyg\u0142osi\u0142 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=0wvUyjexoIg\">referat<\/a><\/noindex> wyst\u0105pienie na temat automatyzacji rozwoju w CIAN: aby upro\u015bci\u0107 \u017cycie i prac\u0119, u\u017cywamy naszej w\u0142asnej platformy Integro. \u015aledzi ona cykl \u017cycia zada\u0144, odci\u0105\u017ca programist\u00f3w od rutynowych operacji i znacznie redukuje liczb\u0119 b\u0142\u0119d\u00f3w w produkcji. W tym wpisie uzupe\u0142nimy wyst\u0105pienie Aleksandra i opowiemy, jak przeszli\u015bmy od prostych skrypt\u00f3w do integracji produkt\u00f3w open source przez nasz\u0105 w\u0142asn\u0105 platform\u0119 oraz czym zajmuje si\u0119 nasz zesp\u00f3\u0142 ds. automatyzacji.<br \/>\n\u00a0<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Poziom zerowy<\/h2>\n<p>\n<i><b>\u201ePoziomu zerowego nie ma, nie znam czego\u015b takiego\u201d<\/b><br \/>\nMistrz Shifu z filmu \u201eKung Fu Panda\u201d<\/i><\/p>\n<p>Automatyzacja w CIAN zacz\u0119\u0142a si\u0119 14 lat po za\u0142o\u017ceniu firmy. Wtedy w zespole programistycznym by\u0142o 35 os\u00f3b. Trudno w to uwierzy\u0107, prawda? Oczywi\u015bcie, w jakiej\u015b formie automatyzacja faktycznie istnia\u0142a, ale osobny kierunek dotycz\u0105cy ci\u0105g\u0142ej integracji i dostarczania kodu zacz\u0105\u0142 si\u0119 kszta\u0142towa\u0107 dopiero w 2015 roku.\u00a0<\/p>\n<p>W tamtym czasie mieli\u015bmy ogromny monolit z Pythonem, C# i PHP, uruchomiony na serwerach Linux\/Windows. Do wdro\u017cenia tego potwora mieli\u015bmy zestaw skrypt\u00f3w, kt\u00f3re uruchamiali\u015bmy r\u0119cznie. By\u0142o te\u017c budowanie monolitu, kt\u00f3re przynosi\u0142o b\u00f3l i cierpienie z powodu konflikt\u00f3w przy \u0142\u0105czeniu ga\u0142\u0119zi, poprawkach b\u0142\u0119d\u00f3w i ponownym budowaniu \u201ez innym zestawem zada\u0144 w budowaniu\u201d. Uproszczony proces wygl\u0105da\u0142 tak:<\/p>\n<p><img decoding=\"async\" alt=\"Od skrypt\u00f3w do w\u0142asnej platformy: jak zautomatyzowali\u015bmy rozw\u00f3j w CIAN\" src=\"\/wp-content\/uploads\/2020\/01\/03c4dd97e2ba0073bab1c33f6003a9ec.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNie satysfakcjonowa\u0142o nas to, chcieli\u015bmy zbudowa\u0107 powtarzalny, zautomatyzowany i zarz\u0105dzany proces budowy i wdro\u017cenia. Do tego potrzebny by\u0142 nam system CI\/CD, a my wybierali\u015bmy mi\u0119dzy bezp\u0142atn\u0105 wersj\u0105 Teamcity a bezp\u0142atnym Jenkins, poniewa\u017c pracowali\u015bmy z nimi i obie odpowiada\u0142y nam funkcjonalno\u015bciami. Wyb\u00f3r pad\u0142 na Teamcity jako na nowszy produkt. Wtedy jeszcze nie u\u017cywali\u015bmy architektury mikroserwis\u00f3w i nie przewidywali\u015bmy du\u017cej liczby zada\u0144 i projekt\u00f3w.<\/p>\n<h2>Przechodzimy do pomys\u0142u stworzenia w\u0142asnego systemu<\/h2>\n<p>\nWdro\u017cenie Teamcity zredukowa\u0142o tylko cz\u0119\u015b\u0107 pracy r\u0119cznej: pozosta\u0142o jeszcze tworzenie Pull Request\u00f3w, przesuwanie zada\u0144 wed\u0142ug status\u00f3w w Jira i wyb\u00f3r zada\u0144 do wydania. Z tym system Teamcity ju\u017c sobie nie radzi\u0142. Nale\u017ca\u0142o wybra\u0107 kierunek dalszej automatyzacji. Rozwa\u017cali\u015bmy opcje pracy ze skryptami w Teamcity lub przej\u015bcie na zewn\u0119trzne systemy automatyzacji. Ostatecznie zdecydowali\u015bmy, \u017ce potrzebna jest maksymalna elastyczno\u015b\u0107, kt\u00f3r\u0105 daje tylko w\u0142asne rozwi\u0105zanie. Tak powsta\u0142a pierwsza wersja wewn\u0119trznego systemu automatyzacji o nazwie Integro.<\/p>\n<p>Teamcity zajmuje si\u0119 automatyzacj\u0105 na poziomie uruchamiania proces\u00f3w budowy i wdro\u017cenia, podczas gdy Integro skupi\u0142o si\u0119 na wy\u017cszej automatyzacji proces\u00f3w rozwoju. Nale\u017ca\u0142o po\u0142\u0105czy\u0107 prac\u0119 z zadaniami w Jira z przetwarzaniem powi\u0105zanego kodu \u017ar\u00f3d\u0142owego w Bitbucket. Na tym etapie w Integro zacz\u0119\u0142y pojawia\u0107 si\u0119 w\u0142asne workflow do pracy z r\u00f3\u017cnymi typami zada\u0144.\u00a0<\/p>\n<p>W wyniku zwi\u0119kszonej automatyzacji w procesach biznesowych wzros\u0142a liczba projekt\u00f3w i run\u00f3w w Teamcity. Tak pojawi\u0142 si\u0119 nowy problem: jeden darmowy instans Teamcity przesta\u0142 wystarcza\u0107 (3 agenty i 100 projekt\u00f3w), dodali\u015bmy kolejny instans (kolejne 3 agenty i 100 projekt\u00f3w), potem jeszcze jeden. W rezultacie otrzymali\u015bmy system sk\u0142adaj\u0105cy si\u0119 z kilku klastr\u00f3w, kt\u00f3ry by\u0142 trudny w zarz\u0105dzaniu:<\/p>\n<p><img decoding=\"async\" alt=\"Od skrypt\u00f3w do w\u0142asnej platformy: jak zautomatyzowali\u015bmy rozw\u00f3j w CIAN\" src=\"\/wp-content\/uploads\/2020\/01\/d95565e01e70e31f6b139dfb9b9caf95.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKiedy stan\u0105\u0142 przed nami problem czwartego instansu, zrozumieli\u015bmy, \u017ce nie mo\u017cemy dalej tak funkcjonowa\u0107, poniewa\u017c skumulowane koszty wsparcia czterech instans\u00f3w wymkn\u0119\u0142y si\u0119 spod kontroli. Pojawi\u0142a si\u0119 kwestia zakupu p\u0142atnej wersji Teamcity lub wyboru darmowego Jenkins. Przeprowadzili\u015bmy obliczenia dotycz\u0105ce instans\u00f3w i plan\u00f3w automatyzacji oraz zdecydowali\u015bmy, \u017ce b\u0119dziemy korzysta\u0107 z Jenkins. Po kilku tygodniach przeszli\u015bmy na Jenkins i pozbyli\u015bmy si\u0119 cz\u0119\u015bci b\u00f3lu g\u0142owy zwi\u0105zanego z utrzymywaniem kilku instans\u00f3w Teamcity. Dzi\u0119ki temu mogli\u015bmy skupi\u0107 si\u0119 na rozwijaniu Integro i dostosowywaniu Jenkins do w\u0142asnych potrzeb.<\/p>\n<p>Wraz z rozwojem podstawowej automatyzacji (w postaci automatycznego tworzenia Pull Request\u00f3w, zbierania i publikowania pokrycia kodu oraz innych kontrol) pojawi\u0142a si\u0119 silna ch\u0119\u0107 maksymalnego ograniczenia r\u0119cznych wyda\u0144 i oddania tej pracy robotom. Ponadto w firmie rozpocz\u0119\u0142a si\u0119 migracja na mikroserwisy, kt\u00f3re wymaga\u0142y cz\u0119stych wyda\u0144, przy czym ka\u017cde z nich oddzielnie. Stopniowo przeszli\u015bmy do automatycznych wyda\u0144 naszych mikroserwis\u00f3w (monolit na razie wydajemy r\u0119cznie z powodu z\u0142o\u017cono\u015bci procesu). Ale, jak to zwykle bywa, pojawi\u0142 si\u0119 nowy problem.\u00a0<\/p>\n<h2>Automatyzujemy testowanie<\/h2>\n<p>\n<img decoding=\"async\" alt=\"Od skrypt\u00f3w do w\u0142asnej platformy: jak zautomatyzowali\u015bmy rozw\u00f3j w CIAN\" src=\"\/wp-content\/uploads\/2020\/01\/9518ee0956922c6eb615bdef068ac525.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDzi\u0119ki automatyzacji wyda\u0144 procesy programowania przyspieszy\u0142y, cz\u0119\u015bciowo kosztem pomijania niekt\u00f3rych etap\u00f3w testowania. To z kolei doprowadzi\u0142o do czasowej utraty jako\u015bci. Brzmi banalnie, ale wraz z przyspieszeniem wydania nale\u017ca\u0142o zmieni\u0107 tak\u017ce metodologi\u0119 rozwoju produktu. Trzeba by\u0142o pomy\u015ble\u0107 o automatyzacji testowania, wdro\u017ceniu osobistej odpowiedzialno\u015bci (tu m\u00f3wimy o \u201eprzyj\u0119ciu idei w g\u0142owie\u201d, a nie o karach finansowych) programisty za wydany kod i b\u0142\u0119dy w nim, a tak\u017ce o decyzji dotycz\u0105cej wydania \/ niewydania zadania poprzez automatyczny deployment.\u00a0<\/p>\n<p>Eliminuj\u0105c problemy z jako\u015bci\u0105, doszli\u015bmy do dw\u00f3ch wa\u017cnych rozwi\u0105za\u0144: zacz\u0119li\u015bmy przeprowadza\u0107 testy kaskadowe i wdro\u017cyli\u015bmy automatyczne monitorowanie b\u0142\u0119d\u00f3w w tle z automatyczn\u0105 reakcj\u0105 na jego przekroczenie. Pierwsze rozwi\u0105zanie pozwoli\u0142o znale\u017a\u0107 oczywiste b\u0142\u0119dy zanim kod trafi\u0142 do produkcji, drugie zmniejszy\u0142o czas reakcji na problemy w produkcji. B\u0142\u0119dy si\u0119 zdarzaj\u0105, ale wi\u0119ksz\u0105 cz\u0119\u015b\u0107 czasu i wysi\u0142k\u00f3w sp\u0119dzamy nie na ich naprawie, ale na minimalizacji.\u00a0<\/p>\n<h2>Zesp\u00f3\u0142 automatyzacji<\/h2>\n<p>\nAktualnie mamy zesp\u00f3\u0142 sk\u0142adaj\u0105cy si\u0119 z 130 programist\u00f3w, i wci\u0105\u017c <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/article\/469965\/\">ro\u015bniemy<\/a><\/noindex>. Zesp\u00f3\u0142 zajmuj\u0105cy si\u0119 ci\u0105g\u0142\u0105 integracj\u0105 i dostarczaniem kodu (dalej \u2014 zesp\u00f3\u0142 Deploy and Integration lub DI) sk\u0142ada si\u0119 z 7 os\u00f3b i pracuje w 2 obszarach: rozw\u00f3j platformy automatyzacji Integro oraz DevOps.\u00a0<\/p>\n<p>Zesp\u00f3\u0142 DevOps odpowiada za \u015brodowiska Dev\/Beta strony CIAN, \u015brodowiska Integro, wspiera programist\u00f3w w rozwi\u0105zywaniu problem\u00f3w oraz opracowuje nowe podej\u015bcia do skalowania \u015brodowisk. Kierunek rozwoju Integro zajmuje si\u0119 zar\u00f3wno sam\u0105 Integro, jak i us\u0142ugami pokrewnymi, na przyk\u0142ad wtyczkami do Jenkins, Jira, Confluence, a tak\u017ce opracowuje pomocnicze narz\u0119dzia i aplikacje dla zespo\u0142\u00f3w deweloperskich.\u00a0<\/p>\n<p>Zesp\u00f3\u0142 DI wsp\u00f3\u0142pracuje z zespo\u0142em Platformy, kt\u00f3ry zajmuje si\u0119 projektowaniem architektury, bibliotek oraz podej\u015bciem do rozwoju wewn\u0105trz firmy. Dodatkowo ka\u017cdy programista w CIAN mo\u017ce przyczyni\u0107 si\u0119 do automatyzacji, na przyk\u0142ad wprowadzi\u0107 mikroautomatyzacj\u0119 pod potrzeby zespo\u0142u lub podzieli\u0107 si\u0119 \u015bwietnym pomys\u0142em, jak jeszcze poprawi\u0107 automatyzacj\u0119.<\/p>\n<h2>Warstwowe podej\u015bcie do automatyzacji w CIAN<\/h2>\n<p>\n<img decoding=\"async\" alt=\"Od skrypt\u00f3w do w\u0142asnej platformy: jak zautomatyzowali\u015bmy rozw\u00f3j w CIAN\" src=\"\/wp-content\/uploads\/2020\/01\/22dcd2d0cc283d53bdaac081885657f8.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWszystkie systemy zaanga\u017cowane w automatyzacj\u0119 mo\u017cna podzieli\u0107 na kilka warstw:<\/p>\n<ol>\n<li>Systemy zewn\u0119trzne (Jira, Bitbucket itp.). Z nimi pracuj\u0105 zespo\u0142y deweloperskie.\n<\/li>\n<li>Platforma Integro. Najcz\u0119\u015bciej programi\u015bci nie pracuj\u0105 z ni\u0105 bezpo\u015brednio, ale to ona wspiera dzia\u0142anie ca\u0142ej automatyzacji.\n<\/li>\n<li>Us\u0142ugi dostarczania, orkiestracji i odkrywania (na przyk\u0142ad Jenkins, Consul, Nomad). Dzi\u0119ki nim wdra\u017camy kod na serwerach i zapewniamy wsp\u00f3\u0142prac\u0119 us\u0142ug.\n<\/li>\n<li>Poziom fizyczny (serwery, systemy operacyjne, oprogramowanie pokrewne). Na tym poziomie dzia\u0142a nasz kod. Mo\u017ce to by\u0107 zar\u00f3wno serwer fizyczny, jak i wirtualny (LXC, KVM, Docker).\n<\/li>\n<\/ol>\n<p>\nNa podstawie tej koncepcji dzielimy obszary odpowiedzialno\u015bci wewn\u0105trz zespo\u0142u DI. Dwa pierwsze poziomy le\u017c\u0105 w zakresie odpowiedzialno\u015bci kierunku rozwoju Integro, a dwa ostatnie poziomy ju\u017c w zakresie odpowiedzialno\u015bci DevOps. Takie podzia\u0142 pozwala skupi\u0107 si\u0119 na zadaniach i nie przeszkadza w interakcji, poniewa\u017c znajdujemy si\u0119 blisko siebie i nieustannie wymieniamy si\u0119 wiedz\u0105 i do\u015bwiadczeniem.<\/p>\n<h2>Integro<\/h2>\n<p>\nSkupimy si\u0119 na Integro i zaczniemy od stosu technologicznego:<\/p>\n<ul>\n<li>CentOS 7\n<\/li>\n<li>Docker + Nomad + Consul + Vault\n<\/li>\n<li>Java 11 (stary monolit Integro pozostanie na 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 (embedded)\n<\/li>\n<li>Grafana + Graphite + Prometheus + Jaeger + ELK\n<\/li>\n<li>Interfejs webowy: React (CSR) + MobX\n<\/li>\n<li>SSO: Keycloak\n<\/li>\n<\/ul>\n<p>\nTrzymamy si\u0119 zasady rozwijania mikrous\u0142ug, cho\u0107 mamy te\u017c spu\u015bcizn\u0119 w postaci monolitu wczesnej wersji Integro. Ka\u017cda mikrous\u0142uga dzia\u0142a w swoim w\u0142asnym kontenerze docker, a us\u0142ugi komunikuj\u0105 si\u0119 ze sob\u0105 za pomoc\u0105 zapyta\u0144 HTTP i wiadomo\u015bci RabbitMQ. Mikrous\u0142ugi odnajduj\u0105 si\u0119 nawzajem przez Consul i wykonuj\u0105 do niego zapytania, przechodz\u0105c autoryzacj\u0119 przez SSO (Keycloak, OAuth 2\/OpenID Connect).<\/p>\n<p><img decoding=\"async\" alt=\"Od skrypt\u00f3w do w\u0142asnej platformy: jak zautomatyzowali\u015bmy rozw\u00f3j w CIAN\" src=\"\/wp-content\/uploads\/2020\/01\/e7630c0bd62a40f397de1bf1c1097926.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJako realistyczny przyk\u0142ad rozwa\u017cmy interakcj\u0119 z Jenkins, kt\u00f3ra sk\u0142ada si\u0119 z nast\u0119puj\u0105cych krok\u00f3w:<\/p>\n<ol>\n<li>Mikrous\u0142uga zarz\u0105dzania workflow (dalej mikrous\u0142uga Flow) chce uruchomi\u0107 budow\u0119 w Jenkins. W tym celu za po\u015brednictwem Consul odnajduje IP:PORT mikrous\u0142ugi integracji z Jenkins (dalej mikrous\u0142uga Jenkins) i wysy\u0142a do niej asynchroniczne zapytanie o uruchomienie budowy w Jenkins.\n<\/li>\n<li>Mikrous\u0142uga Jenkins po otrzymaniu zapytania formu\u0142uje i zwraca w odpowiedzi identyfikator zadania (Job ID), dzi\u0119ki kt\u00f3remu b\u0119dzie mo\u017cna p\u00f3\u017aniej zidentyfikowa\u0107 wynik pracy. Jednocze\u015bnie uruchamia budow\u0119 w Jenkins poprzez wywo\u0142anie REST API.\n<\/li>\n<li>Jenkins przeprowadza budow\u0119, a po jej zako\u0144czeniu wysy\u0142a webhook z wynikami wykonania do mikrous\u0142ugi Jenkins.\n<\/li>\n<li>Mikrous\u0142uga Jenkins, po otrzymaniu webhooka, formu\u0142uje komunikat o zako\u0144czeniu przetwarzania zapytania i do\u0142\u0105cza do niego wyniki wykonania. Sformu\u0142owany komunikat jest wysy\u0142any do kolejki RabbitMQ.\n<\/li>\n<li>Poprzez RabbitMQ opublikowany komunikat trafia do mikrous\u0142ugi Flow, kt\u00f3ra dowiaduje si\u0119 o wyniku przetwarzania swojego zadania, por\u00f3wnuj\u0105c identyfikator zadania (Job ID) z zapytania i otrzymanego komunikatu.\n<\/li>\n<\/ol>\n<p>\nObecnie mamy oko\u0142o 30 mikrous\u0142ug, kt\u00f3re mo\u017cna podzieli\u0107 na kilka grup:<\/p>\n<ol>\n<li>Zarz\u0105dzanie konfiguracjami.\n<\/li>\n<li>Informowanie i interakcja z u\u017cytkownikami (messengery, e-mail).\n<\/li>\n<li>Praca z kodem \u017ar\u00f3d\u0142owym.\n<\/li>\n<li>Integracja z narz\u0119dziami do wdra\u017cania (jenkins, nomad, consul itp.).\n<\/li>\n<li>Monitorowanie (wydania, b\u0142\u0119dy itp.).\n<\/li>\n<li>Webowe narz\u0119dzia (interfejs do zarz\u0105dzania \u015brodowiskami testowymi, zbierania statystyk itp.).\n<\/li>\n<li>Integracja z trackerami zada\u0144 i podobnymi systemami.\n<\/li>\n<li>Zarz\u0105dzanie workflow dla r\u00f3\u017cnych zada\u0144.\n<\/li>\n<\/ol>\n<p><\/p>\n<h2>Workflow zadania<\/h2>\n<p>\nIntegro automatyzuje dzia\u0142ania zwi\u0105zane z cyklem \u017cycia zadania. W uproszczeniu przez cykl \u017cycia zadania rozumiemy workflow zadania w Jira. W naszych procesach rozwoju istnieje kilka wariacji workflow w zale\u017cno\u015bci od projektu, typu zadania i opcji wybranych w konkretnej sprawie.\u00a0<\/p>\n<p>Rozwa\u017cmy workflow, z kt\u00f3rego korzystamy najcz\u0119\u015bciej:<\/p>\n<p><img decoding=\"async\" alt=\"Od skrypt\u00f3w do w\u0142asnej platformy: jak zautomatyzowali\u015bmy rozw\u00f3j w CIAN\" src=\"\/wp-content\/uploads\/2020\/01\/62555be6bab024dd30f3cf70d4fe3cba.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNa schemacie k\u00f3\u0142ko z\u0119bate wskazuje, \u017ce przej\u015bcie jest wywo\u0142ywane automatycznie przez Integro, podczas gdy posta\u0107 cz\u0142owieka oznacza, \u017ce przej\u015bcie jest wywo\u0142ywane r\u0119cznie przez cz\u0142owieka. Przyjrzyjmy si\u0119 kilku \u015bcie\u017ckom, kt\u00f3rymi zadanie mo\u017ce przej\u015b\u0107 w tym workflow.<\/p>\n<p>Ca\u0142kowicie r\u0119czne testowanie na DEV+BETA bez test\u00f3w kanaryjskich (zazwyczaj w ten spos\u00f3b wydajemy monolit):<\/p>\n<p><img decoding=\"async\" alt=\"Od skrypt\u00f3w do w\u0142asnej platformy: jak zautomatyzowali\u015bmy rozw\u00f3j w CIAN\" src=\"\/wp-content\/uploads\/2020\/01\/775528862e14817dff5f69db6de654dd.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMog\u0105 wyst\u0119powa\u0107 tak\u017ce inne kombinacje przej\u015b\u0107. Czasami \u015bcie\u017ck\u0119, kt\u00f3r\u0105 pod\u0105\u017cy zadanie, mo\u017cna wybra\u0107 za pomoc\u0105 opcji w Jira.<\/p>\n<h2>Ruch zadania<\/h2>\n<p>\nPrzyjrzyjmy si\u0119 podstawowym krokom, kt\u00f3re s\u0105 podejmowane podczas ruchu zadania w workflow \u201eTestowanie na DEV + testy kanaryjskie\u201d:<\/p>\n<p>1. Programista lub PM tworzy zadanie.<\/p>\n<p>2. Programista podejmuje si\u0119 zadania. Po zako\u0144czeniu przenosi je w status IN REVIEW.<\/p>\n<p>3. Jira wysy\u0142a webhook do mikroserwisu Jira (odpowiada za integracj\u0119 z Jira).<\/p>\n<p>4. Mikroserwis Jira wysy\u0142a zapytanie do serwisu Flow (odpowiada za wewn\u0119trzne workflow, w kt\u00f3rych wykonywana jest praca) w celu uruchomienia workflow.<\/p>\n<p>5. Wewn\u0105trz serwisu Flow:<\/p>\n<ul>\n<li>Przypisywani s\u0105 recenzenci do zadania (mikroserwis Users, kt\u00f3ry zna wszystkich u\u017cytkownik\u00f3w + mikroserwis Jira).<\/li>\n<li>Za po\u015brednictwem mikroserwisu Source (znaj\u0105cego repozytoria i ga\u0142\u0119zie, ale nie pracuj\u0105cego z samym kodem) przeprowadzany jest przeszukiwanie repozytori\u00f3w, w kt\u00f3rych znajduje si\u0119 ga\u0142\u0105\u017a naszego zadania (dla uproszczenia wyszukiwania nazwa ga\u0142\u0119zi pokrywa si\u0119 z numerem zadania w Jira). Najcz\u0119\u015bciej zadanie ma tylko jedn\u0105 ga\u0142\u0105\u017a w jednym repozytorium, co upraszcza zarz\u0105dzanie kolejk\u0105 na wdro\u017cenie i zmniejsza powi\u0105zania mi\u0119dzy repozytoriami.<\/li>\n<li>Dla ka\u017cdej znalezionej ga\u0142\u0119zi wykonywana jest nast\u0119puj\u0105ca sekwencja dzia\u0142a\u0144:\n<p> i) Podlewanie ga\u0142\u0119zi master (mikroserwis Git do pracy z kodem).<br \/>\n ii) Ga\u0142\u0105\u017a jest blokowana przed zmianami przez programist\u0119 (mikroserwis Bitbucket).<br \/>\n iii) Tworzony jest Pull Request dla tej ga\u0142\u0119zi (mikroserwis Bitbucket).<br \/>\n iv) Wysy\u0142ana jest wiadomo\u015b\u0107 o nowym Pull Reque\u015bcie do czat\u00f3w programist\u00f3w (mikroserwis Notify do pracy z powiadomieniami).<br \/>\n v) Rozpoczynaj\u0105 si\u0119 budowanie, testowanie i wdro\u017cenie zadania na DEV (mikroserwis Jenkins do pracy z Jenkins).<br \/>\n vi) Je\u015bli wszystkie poprzednie punkty zako\u0144czy\u0142y si\u0119 sukcesem, to Integro wydaje swoje zatwierdzenie w Pull Reque\u015bcie (mikroserwis Bitbucket).<\/li>\n<li>Integro oczekuje na zatwierdzenie w Pull Reque\u015bcie od przypisanych recenzent\u00f3w.<\/li>\n<li>Gdy otrzymane zostan\u0105 wszystkie niezb\u0119dne zatwierdzenia (w tym pozytywne wyniki test\u00f3w automatycznych), Integro przenosi zadanie w status Test on Dev (mikroserwis Jira).<\/li>\n<\/ul>\n<p>\n6. Testerzy przeprowadzaj\u0105 testy zadania. Je\u015bli nie ma problem\u00f3w, zmieniaj\u0105 status zadania na Gotowe do Budowy.<\/p>\n<p>7. Integro \u201ewidzi\u201d, \u017ce zadanie jest gotowe do wydania, i uruchamia jego wdro\u017cenie w trybie kanaryjnym (mikroserwis Jenkins). Gotowo\u015b\u0107 do wydania okre\u015blona jest przez zestaw regu\u0142. Na przyk\u0142ad, zadanie ma w\u0142a\u015bciwy status, nie ma blokad na inne zadania, nie ma aktywnych wdro\u017ce\u0144 tego mikroserwisu itd.<\/p>\n<p>8. Zadanie zostaje przeniesione do statusu Kanaryjnego (mikroserwis Jira).<\/p>\n<p>9. Jenkins uruchamia wdro\u017cenie zadania w trybie kanaryjnym przez Nomad (zazwyczaj 1-3 instancje) i powiadamia o wdro\u017ceniu mikroserwis monitoruj\u0105cy wydania (mikroserwis DeployWatch).<\/p>\n<p>10. Mikroserwis DeployWatch zbiera t\u0142o b\u0142\u0119d\u00f3w i reaguje na nie, je\u017celi to konieczne. W przypadku przekroczenia t\u0142a b\u0142\u0119d\u00f3w (norma t\u0142a obliczana jest automatycznie) nast\u0119puje powiadomienie programist\u00f3w przez mikroserwis Notify. Je\u015bli programista nie zareagowa\u0142 w ci\u0105gu 5 minut (nie klikn\u0105\u0142 Revert ani Stay), automatycznie uruchamiany jest rollback instancji kanaryjnych. Je\u015bli t\u0142o b\u0142\u0119d\u00f3w nie zosta\u0142o przekroczone, programista musi r\u0119cznie uruchomi\u0107 wdro\u017cenie zadania na Production (klikaj\u0105c przycisk w interfejsie). Je\u015bli w ci\u0105gu 60 minut programista nie uruchomi\u0142 wdro\u017cenia na Production, instancje kanaryjne r\u00f3wnie\u017c dla bezpiecze\u0144stwa zostan\u0105 wycofane.<\/p>\n<p>11. Po uruchomieniu wdro\u017cenia na Production:<\/p>\n<ul>\n<li>Zadanie zostaje przeniesione do statusu Produkcyjnego (mikroserwis Jira).<\/li>\n<li>Mikroserwis Jenkins uruchamia proces wdro\u017cenia i powiadamia o wdro\u017ceniu mikroserwis DeployWatch.<\/li>\n<li>Mikroserwis DeployWatch sprawdza, czy wszystkie kontenery na Production zosta\u0142y zaktualizowane (by\u0142y przypadki, gdy nie wszystkie by\u0142y aktualizowane).<\/li>\n<li>Przez mikroserwis Notify wysy\u0142ane jest powiadomienie o wynikach wdro\u017cenia na Production.<\/li>\n<\/ul>\n<p>\n12. Programi\u015bci b\u0119d\u0105 mieli 30 minut na uruchomienie rollbacku zadania z Production w przypadku stwierdzenia nieprawid\u0142owego dzia\u0142ania mikroserwisu. Po up\u0142ywie tego czasu zadanie zostanie automatycznie po\u0142\u0105czone z masterem (mikroserwis Git).<\/p>\n<p>13. Po pomy\u015blnym po\u0142\u0105czeniu z masterem status zadania zostanie zmieniony na Zamkni\u0119ty (mikroserwis Jira).<\/p>\n<p>Schemat nie ro\u015bci sobie pretensji do pe\u0142nej szczeg\u00f3\u0142owo\u015bci (w rzeczywisto\u015bci krok\u00f3w jest jeszcze wi\u0119cej), ale pozwala oceni\u0107 stopie\u0144 integracji w procesy. Nie uwa\u017camy tej schematu za idealny i stale udoskonalamy procesy automatycznego wsparcia wyda\u0144 i wdro\u017ce\u0144.<\/p>\n<h2>Co dalej<\/h2>\n<p>\nMamy wielkie plany dotycz\u0105ce rozwoju automatyzacji, na przyk\u0142ad rezygnacja z r\u0119cznych operacji podczas wydania monolitu, poprawa monitorowania podczas automatycznego wdra\u017cania, a tak\u017ce lepsza wsp\u00f3\u0142praca z programistami.<\/p>\n<p>Na tym etapie zatrzymamy si\u0119. Wiele temat\u00f3w poruszonych w przegl\u0105dzie automatyzacji om\u00f3wili\u015bmy powierzchownie, niekt\u00f3re w og\u00f3le nie by\u0142y poruszone, dlatego ch\u0119tnie odpowiemy na pytania. Czekamy na propozycje, co szczeg\u00f3\u0142owo om\u00f3wi\u0107, piszcie w komentarzach.<br \/>\n<br \/>\u0179r\u00f3d\u0142o: <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.1.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\/pl\/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.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\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\/pl\/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\udd47Od skrypt\u00f3w do w\u0142asnej platformy: jak zautomatyzowali\u015bmy rozw\u00f3j w CIAN | ProHoster","description":"Na RIT 2019.","canonical_url":"https:\/\/prohoster.info\/pl\/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":"pl_PL","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\/pl\/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\/pl\/wp-json\/wp\/v2\/posts\/55870","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=55870"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/55870\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=55870"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=55870"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=55870"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}