Dyrektor ds. eksploatacji portalu Banki.ru, Andriej Nikolski, opowiedział na zeszłorocznej konferencji o serwisach-sierotach: jak rozpoznać sierotę w infrastrukturze, jakie słabości mają serwisy-sieroty, co z nimi zrobić i jak postępować, jeśli nic nie pomaga.
Pod katem znajduje się tekstowa wersja referatu.

Witam, koledzy! Nazywam się Andriej, kieruję eksploatacją w firmie Banki.ru.
Mamy duże serwisy, to są takie monolitowe serwisy, są serwisy w bardziej klasycznym rozumieniu, i są zupełnie małe. W mojej roboczej terminologii mówię, że jeśli serwis jest prosty i mały, to jest mikro, a jeśli nie jest bardzo prosty i nie jest mały, to jest po prostu serwis.
Zalety serwisów
Szybko przelecę przez zalety serwisów.

Po pierwsze — skalowanie. Możesz szybko zrobić coś na serwisie i uruchomić w produkcji. Jeśli masz napływ ruchu, klonujesz serwis. Gdy przychodzi kolejny ruch, klonujesz jeszcze raz i z tym żyjesz. To dobra zaleta, i w zasadzie, kiedy zaczynaliśmy, uważaliśmy to za najważniejsze, dlaczego w ogóle to robimy.

Po drugie, izolowany rozwój, gdy masz kilka zespołów deweloperskich, kilku różnych programistów w każdym zespole, i każdy zespół tworzy jakiś własny serwis.
Z zespołami pojawia się pewien niuans. Programiści mogą być różni. I na przykład istnieją . Po raz pierwszy zobaczyłem to u Maksima Dorofiewa. Czasami ludzie-płatki śniegu są w niektórych zespołach, a w innych ich nie ma. Sprawia to, że różne serwisy używane w firmie są nieco nierównomierne.

Zobacz na obrazek: to dobry programista, ma duże ręce, może zrobić wiele. Główna problem — skąd pochodzą te ręce.

Serwisy dają możliwość korzystania z różnych języków programowania, bardziej odpowiednich do różnych zadań. Jakiś serwis na Go, jakiś na Erlangu, jakiś na Rubym, coś na PHP, coś na Pythonie. Ogólnie można się rozwinąć bardzo szeroko. Tu również są pewne niuanse.

Architektura oparta na serwisach to przede wszystkim kwestia devops. To znaczy, jeśli nie masz automatyzacji, nie masz procesu wdrażania, jeśli konfigurujesz ręcznie, twoje konfiguracje mogą się różnić między instancjami serwisu, i musisz tam interweniować, to jesteś w piekle.
Na przykład, jeśli masz 20 usług i musisz je wdrażać ręcznie, masz 20 konsol i jednocześnie wciskasz „enter” jak ninja. To nie jest zbyt dobre.
Jeśli masz usługę po testach (jeśli są testy, oczywiście) i musisz ją jeszcze dopracować, aby działała w produkcji, mam dla ciebie złe wieści.
Jeśli polegasz na specyficznych usługach Amazona i pracujesz przy tym w Rosji, to dwa miesiące temu również miałeś „Wszystko wokół płonie, jest dobrze, wszystko jest super”.

Używamy Ansible do automatyzacji wdrażania, Puppet do spójności, Bamboo do automatyzacji wdrożeń, Confluence, aby to wszystko jakoś opisać.
Nie będę się tym szczegółowo zajmował, ponieważ wystąpienie dotyczy bardziej praktyk interakcji niż technicznej realizacji.

Mieliśmy na przykład problemy, gdy Puppet na serwerze działa z Ruby 2, a jakaś aplikacja jest napisana pod Ruby 1.8 i razem nie działają. Pojawia się jakiś błąd. A gdy trzeba trzymać na jednej maszynie kilka wersji Ruby, zazwyczaj zaczynają się problemy.
Na przykład, każdemu programiście wydajemy środowisko, w którym jest prawie wszystko, co mamy, wszystkie usługi, które można rozwijać, aby miał izolowane środowisko, mógł je psuć i budować, jak chce.
Czasami potrzebny jest specjalnie skompilowany pakiet z obsługą czegoś tam. To jest dość trudne. Słuchałem wystąpienia, w którym obraz dockera ważył 45 GB. W Linuksie jest, oczywiście, prościej, tam wszystko jest mniejsze, ale i tak nie ma wystarczająco dużo miejsca.
Czasem występują sprzeczne zależności, gdy jedna część projektu zależy od biblioteki jednej wersji, a inna część projektu od innej wersji, a biblioteki razem w ogóle się nie instalują.

Mamy strony i usługi na PHP 5.6, wstydzimy się za to, ale co zrobić. To jest nasze jedno środowisko. Są strony i usługi na PHP 7, jest ich więcej, nie wstydzimy się za nie. I każdy programista ma swoją bazę, gdzie radośnie przerabia.
Jeśli w firmie piszesz w jednym języku, trzy wirtualki na programistę brzmią całkiem normalnie. Jeśli masz różne języki programowania, sytuacja staje się gorsza.

Tworzysz strony i usługi, a potem jeszcze jedna platforma dla Go, jedna dla Ruby, a obok jeszcze jakiś Redis. W rezultacie wszystko to zamienia się w duże pole wsparcia, i cały czas coś może się zepsuć.

Dlatego zastąpiliśmy wygodne elementy języka programowania używaniem różnych frameworków, ponieważ frameworki PHP są dość różne, mają różne możliwości, różne społeczności, różne wsparcie. Można pisać usługi tak, aby mieć już coś gotowego pod nie.
Każda usługa ma swoją ekipę

Naszym głównym atutem, który wykrystalizował się przez kilka lat, jest to, że każda usługa ma swoją ekipę. To wygodne w dużym projekcie, można zaoszczędzić czas na dokumentacji, menedżerowie dobrze znają swój projekt.
Zadania związane ze wsparciem można świetnie kierować. Na przykład, gdy zepsuje się usługa ubezpieczeń. Od razu zespół zajmujący się ubezpieczeniami przystępuje do naprawy.
Nowe funkcje powstają szybko, ponieważ gdy masz jedną, jakąś atomową usługę, można w nią szybko coś wprowadzić.
I kiedy zepsujesz swoją usługę, co jest nieuniknione, nie wpływa to na inne usługi, i nie przybiegają do ciebie programiści z innych zespołów z kijami mówiąc: „Aj-aj, nie rób tak.”

Jak zawsze, są pewne niuanse. Mamy stabilne zespoły, menedżerowie są mocno związani z zespołem. Są wyraźne dokumenty, menedżerowie bacznie to wszystko obserwują. Każdy zespół ma kilka usług ze swoim menedżerem, i jest konkretna dziedzina kompetencji.
Jeśli zespoły są ruchome (co się u nas czasami zdarza), istnieje dobra metoda zwana „mapą gwiazd”.

Masz listę usług i ludzi. Gwiazdka oznacza, że osoba jest ekspertem w tej usłudze, książeczka oznacza, że osoba uczy się tej usługi. Zadaniem osoby jest zamienić książeczkę na gwiazdkę. A jeśli przy usłudze nic nie jest napisane, zaczynają się problemy, o których będę dalej mówić.
Jak pojawiają się usługi-sieroty?

Pierwszym problemem, pierwszym sposobem na uzyskanie usługi-sieroty w swojej infrastrukturze są zwolnienia pracowników. Czy ktoś z Was miał sytuację, kiedy terminy biznesowe pojawiają się, zanim oceni się zadania? Czasami tak się zdarza, że terminy są sztywne i brakuje czasu na dokumentację. „Musimy wprowadzić usługę do produkcji, potem dopiszemy.”
Jeśli zespół jest mały, bywa, że jest tylko jeden programista, który pisze wszystko, a pozostali są na podmianie. „Zrealizowałem główną architekturę, ty zajmij się interfejsami.” Potem w pewnym momencie menedżer na przykład odchodzi. I w tym okresie, kiedy menedżer odszedł, a nowy jeszcze nie został wyznaczony, programiści sami decydują, w jakim kierunku podąża usługa, co się z nią dzieje. A jak wiemy (wróćmy kilka slajdów wstecz), w niektórych zespołach są osoby-wieżowce, czasami wieżowiec to lider zespołu. Potem on odchodzi, i otrzymujemy usługę-sierotę.

Tymczasem zadania od wsparcia i od biznesu nie znikają, osiadają w backlogu. Jeśli podczas tworzenia usługi były jakieś błędy architektoniczne, również osiadają w backlogu. Usługa powoli się degraduje.
Jak rozpoznać sierotę?
Ta lista całkiem dobrze opisuje sytuację. Kto zauważył coś podobnego w swojej infrastrukturze?

O dokumentowanych obejściach: jest usługa, która w zasadzie działa, ma manual na dwie strony, jak z nią pracować, ale nikt nie wie, jak działa wewnątrz.
Albo, na przykład, mamy jakiś skracacz linków. U nas obecnie korzystamy z trzech skracaczy linków do różnych celów w różnych usługach. To są bezpośrednie konsekwencje.

Teraz będę kapitanem oczywistości. Co należy zrobić? Po pierwsze, trzeba przekazać usługę innemu menedżerowi, innemu zespołowi. Jeśli Twój lider zespołu jeszcze nie odszedł, to do tego innego zespołu, kiedy zdajecie sobie sprawę, że usługa przypomina sierotę, trzeba włączyć kogoś, kto cokolwiek o niej wie.
Najważniejsza rzecz: musicie mieć spisane procedury przekazywania, najlepiej z wielką starannością. W naszym przypadku zazwyczaj dbam o to, ponieważ muszę, żeby to wszystko działało. Menedżerowie potrzebują, aby to było szybko oddane, a co się z tym potem stanie, ich już mało interesuje.

Następny sposób na stworzenie sieroty to „Zlećmy to na zewnątrz, to będzie szybsze, a potem przekażemy to zespołowi”. Jasne, że wszyscy mają jakieś plany w zespole, kolejkę. Często zamawiający myśli, że na zleceniu zrobią to tak samo, jak dział techniczny w firmie. Chociaż motywacje są różne. Na zleceniach można spotkać dziwaczne rozwiązania technologiczne i algorytmiczne.

Mieliśmy na przykład serwis, w którym Sphinx znajdował się w różnych nieoczekiwanych miejscach. Później opowiem, co musieliśmy zrobić.
Zleceniobiorcy mają czasami autorskie frameworki. To po prostu czysty PHP z kopiowaniem i wklejaniem z poprzedniego projektu, gdzie można znaleźć różne rzeczy. Duże obejścia w skryptach wdrożeniowych, kiedy trzeba zmieniać kilka linijek w jakimś pliku skomplikowanymi skryptami Bash, które są wywoływane przez jakiś trzeci skrypt. W rezultacie zmieniasz system wdrożeniowy, wybierasz coś innego, a nagle twój serwis nie działa. Ponieważ potrzeba jeszcze 8 linków między różnymi folderami. Czasem jest tak, że tysiąc rekordów działa, a sto tysięcy już nie.
Będę kontynuować dowodzenie. Odbiór usługi z zewnętrznego źródła to procedura obowiązkowa. Który z was miał sytuację, że serwis z outsourcingu przyjeżdża, a jego nikt nie przyjmuje? To nie jest tak popularne jak sierota serwisowa, ale jednak.

Serwis należy sprawdzić, należy go przejrzeć, trzeba zmienić hasła. Mieliśmy przypadek, kiedy dostaliśmy serwis, w którym w panelu administracyjnym było „if login == ‘admin’ && password == ‘admin’…”, dosłownie napisane w kodzie. Siedzimy i myślimy, czy to naprawdę piszą ludzie w 2018 roku?
Testowanie pojemności magazynu to także ważna rzecz. Należy sprawdzić, co się stanie przy stu tysiącach rekordów, nawet zanim ten serwis wprowadzisz do produkcji.

Nie powinno być wstydem wysłać serwis na poprawki. Kiedy mówisz: „Nie przyjmujemy tego serwisu, mamy 20 zadań, zróbcie je, wtedy przyjmiemy”, to jest normalne. Sumienie nie powinno cię boleć, że narażasz menedżera lub że biznes wyda pieniądze. Biznes później wyda więcej.
Mieliśmy sytuację, kiedy zdecydowaliśmy się na zrobienie pilotażowego projektu na zlecenie.

Został oddany na czas, co było jedynym kryterium jakości. Dlatego zrobiono kolejny projekt pilotażowy, już nawet nie do końca pilotażowy. Te usługi zostały przyjęte, administracyjnie powiedziano, oto wasz kod, oto zespół, oto wasz menedżer. Usługi zaczęły przynosić zyski. Jednak w rzeczywistości nadal pozostały osierocone, nikt nie rozumie, jak działają, a menedżerowie wszelkimi sposobami wykręcają się od ich zadań.

Jest jeszcze jedno świetne pojęcie – partyzancka rozwój. Kiedy jakiś dział, zazwyczaj marketingowy, chce przetestować hipotezę i zleca całą usługę na zewnątrz. Zaczyna napływać ruch, zamykają dokumenty, podpisują akty z wykonawcą, wchodzą w eksploatację i mówią: „Ludzie, mamy tutaj usługę, na której już jest ruch, przynosi nam pieniądze, przyjmijmy ją”. My na to: „Oho, jak to się stało”.

I jeszcze jeden sposób na uzyskanie usługi-osieroconej: kiedy jakaś drużyna nagle okazuje się obciążona, kierownictwo mówi: „Przekażmy tę usługę tej drużynie, która ma mniejsze obciążenie”. Potem przekażemy trzeciej grupie i zmienimy menedżera. I w efekcie znów mamy osierocone oprogramowanie.
Jaki jest problem z osieroconymi usługami?

Kto nie wie, to podniesiony w Szwecji okręt liniowy Wasa, słynący z tego, że zatonął pięć minut po wodowaniu. I król Szwecji, nawiasem mówiąc, nikogo za to nie skazał. Budowano go przez dwa pokolenia inżynierów, którzy nie umieli budować takich statków. Efekt był przewidywalny.
Statek mógł zatonąć, nawiasem mówiąc, o wiele gorzej, na przykład gdyby król jechał na nim gdzieś w burzy. A tak, zatonął od razu, według metodyki agile jest to dobrze – porażka na wczesnym etapie.
Jeśli ponieśliśmy porażkę na wczesnym etapie, zazwyczaj nie ma problemów. Na przykład podczas odbioru wysłano do poprawki. A jeśli ponieśliśmy porażkę już na etapie produkcji, kiedy zostały zainwestowane pieniądze, to mogą pojawić się problemy. Skutki, jak to się nazywa w biznesie.
Czym są niebezpieczne usługi-osierocone:
- Usługa może nagle się zepsuć.
- Usługa długo się naprawia lub w ogóle się nie naprawia.
- Problemy z bezpieczeństwem.
- Problemy z ulepszeniami i aktualizacjami.
- Jeżeli ważna usługa się psuje, cierpi reputacja firmy.
Co robić z usługami-osieroconymi?

Jeszcze raz przypomnę, co należy zrobić. Po pierwsze, musi być dokumentacja. 7 lat w Banki.ru nauczyło mnie, że testerzy nie powinni wierzyć słowom programistów, a dział eksploatacji nie powinien wierzyć nikomu na słowo. Należy to sprawdzać.

Po drugie, należy pisać schematy interakcji, ponieważ zdarza się, że usługi, które są akceptowane nie najlepiej, zawierają zależności, o których nikt nie powiedział. Na przykład, programiści powiązali usługę z kluczem do map Yandex lub do Dadata. Kiedy skończył się darmowy limit, wszystko się zepsuło i nie wiesz, co się w ogóle stało. Wszystkie takie pułapki powinny być opisane: w usłudze używa się Dadata, Sms i jeszcze czegoś.

Po trzecie, praca z długiem technicznym. Kiedy robisz jakieś obejścia lub przyjmujesz usługę i mówisz, że coś należy zrobić, należy pilnować, żeby to było zrobione. Bo potem może się okazać, że mała dziura nie jest taka mała i w nią wpadniesz.
Z zadaniami architektonicznymi mieliśmy historię dotyczącą Sphinx. W jednej z usług Sphinx był używany do wprowadzania list. Po prostu lista z paginacją, ale jednocześnie była reindeksowana każdej nocy. Składał się z dwóch indeksów: jeden duży był indeksowany każdej nocy, a do niego był dołączany mały indeks. Każdego dnia, z prawdopodobieństwem 50%, albo wszystko działało, albo nie, przy publikacji indeks się łamał i nasze wiadomości przestawały być aktualizowane na stronie głównej. Na początku trwało to 5 minut, podczas gdy indeks był reindeksowany, potem indeks urósł i w pewnym momencie zaczął reindeksować się przez 40 minut. Kiedy to usunęliśmy, odetchnęliśmy z ulgą, bo było jasne, że minie jeszcze trochę czasu i nasz indeks będzie się reindeksował przez pełen dzień roboczy. To byłby fail dla naszego portalu, osiem godzin bez wiadomości — wszystko, biznes stanął.
Plan pracy z usługą-sierotą

W rzeczywistości, jest to bardzo trudne do zrobienia, ponieważ devops to komunikacja. Chce się być w dobrych relacjach ze swoimi kolegami, a kiedy bijesz kolegów i menedżerów regulacjami po głowie, mogą odczuwać sprzeczne uczucia wobec tych, którzy tak robią.
Oprócz wszystkich tych punktów, jest jeszcze jedna ważna rzecz: za każdy konkretny serwis, za każdy konkretny fragment procedury wdrożenia, muszą odpowiadać konkretne osoby. Kiedy nie ma ludzi i trzeba angażować innych, aby wszystko to zbadać, robi się trudniej.

Jeśli to wszystko nie pomogło, a serwis-sierota wciąż pozostał sierotą, nikt nie chce go przejąć, dokumentacja nie powstaje, a zespół, który został do tego serwisu zaproszony, odmawia wykonania jakichkolwiek działań, istnieje prosty sposób — wszystko przerobić.
To znaczy, że bierzemy wymagania dotyczące serwisu od nowa i piszemy nowy serwis, lepszy, na lepszej platformie, bez dziwnych rozwiązań technologicznych. I migrujemy na niego w trakcie działania.

Mieliśmy sytuację, kiedy wzięliśmy serwis na Yii 1 i zrozumieliśmy, że nie możemy go dalej rozwijać, ponieważ skończyli się programiści, którzy potrafią dobrze pisać na Yii 1. Wszyscy programiści dobrze piszą w Symfony 3. Co zrobić? Przydzieliliśmy czas, przydzieliliśmy zespół, przydzieliliśmy menedżera, przepisaliśmy projekt i płynnie przełączyliśmy na niego ruch.
Po tym stary serwis można usunąć. To moja ulubiona procedura, kiedy z systemu zarządzania konfiguracjami trzeba wziąć i wyczyścić jakiś serwis, a potem sprawdzić, żeby wszystkie maszyny na produkcji były wygaszone, aby programiści nie pozostawili żadnych śladów. Repozytorium w gicie pozostaje.
To wszystko, o czym chciałem opowiedzieć, chętnie podyskutuję, temat jest kontrowersyjny, wielu w nim pływało.
Na slajdach było wspomniane, że ujednoliciliście języki. Jako przykład podano zmianę rozmiaru obrazków. Ale czy naprawdę trzeba to ujednolicać do jednego języka? Bo zmiana rozmiaru obrazka w PHP, no, można było to zrealizować również w Golang.
W rzeczywistości nie jest to konieczne, podobnie jak wszystkie praktyki. W niektórych przypadkach może to być nawet niepożądane. Jednak należy zrozumieć, że jeśli w Twojej firmie jest 50 osób w dziale technicznym, z czego 45 to programiści PHP, 3 to devopsy, którzy znają Pythona, Ansible, Puppet i tym podobne, a tylko jeden z nich pisze serwis w języku Go do resize'u obrazków, to kiedy on odchodzi, jego ekspertyza odchodzi razem z nim. W takim przypadku będziesz musiał poszukiwać specyficznego dewelopera na rynku, który zna ten język, szczególnie jeśli jest on rzadki. To oznacza, że z perspektywy organizacyjnej jest to problematyczne. Z punktu widzenia devopsa, musisz nie tylko sklonować gotowy zestaw playbooków, które używasz do wdrażania usług, ale będziesz musiał je napisać od nowa.
Obecnie tworzymy serwis w Node.js, co będzie przestrzenią dla każdego programisty z osobnym językiem. Jednak zastanawialiśmy się, czy to ma sens. To znaczy, tu chodzi o to, żeby usiąść i pomyśleć.
Jak monitorujecie swoje usługi? Jak zbieracie i śledzicie logi?
Logi zbieramy w Elasticsearch i umieszczamy je w Kibana, w zależności od tego, czy to środowisko produkcyjne czy testowe, używamy różnych zbieraczy. Gdzieś jest Lumberjack, gdzieś jeszcze coś, już nie pamiętam. Są też pewne miejsca w niektórych usługach, gdzie instalujemy Telegraf i wysyłamy je gdzie indziej oddzielnie.
Jak żyć z Puppet i Ansible w jednym środowisku?
W rzeczywistości mamy teraz dwa środowiska, jedno — Puppet, drugie — Ansible. Pracujemy nad ich hybrydyzacją. Ansible to dobre środowisko do wstępnej konfiguracji, Puppet to zła rzecz do wstępnej konfiguracji, ponieważ wymaga ręcznej pracy bezpośrednio z platformą, a Puppet zapewnia zbieżność konfiguracji. To oznacza, że platforma sama się utrzymuje w aktualnym stanie, a aby maszyna z Ansible była utrzymywana w aktualnym stanie, trzeba regularnie uruchamiać na niej playbooki. Oto taka różnica.
Jak utrzymujecie zgodność? Macie konfiguracje zarówno w Ansible, jak i w Puppet?
To nasz duży ból, ręcznie wspieramy kompatybilność i zastanawiamy się, jak przejść od tego wszystkiego gdzie indziej. Okazuje się, że Puppet instaluje pakiety i wspiera tam jakieś odnośniki, a Ansible, na przykład, instaluje kod i dostosowuje tam świeże konfiguracje aplikacji.
W prezentacji było o różnych wersjach Ruby. Jakie rozwiązanie?
Spotkaliśmy się z tym w jednym miejscu i musimy to cały czas mieć na uwadze. Po prostu wyłączyliśmy tę część, która działała na tej wersji Ruby, która była niekompatybilna z aplikacjami, i trzymaliśmy ją osobno.
W tym roku konferencja odbędzie się 7 grudnia w „Technopoli”. Zgłoszenia na referaty przyjmujemy do 11 listopada. do nas, jeśli chcecie wystąpić.
Rejestracja dla uczestników jest otwarta, dołączajcie!
Źródło: habr.com
