W projektach IT bardzo powszechne jest spoglądanie na to, co i jak robią najwięksi gracze na rynku. Lubimy powoływać się na historie gigantów, często nawet nie zastanawiając się nad tym, ile w nich prawdy. Spotify ma znakomitą kulturę bo opiera zarządzanie na Tribes i Squads. Google skaluje się świetnie bo używa Kubernetes. Netflix działa doskonale bo bazuje na mikrousługach. Właśnie, mikrousługach. Przyjrzyjmy się bliżej temu czym są i w czym pomagają mikrousługi (znane również jako microservices).


Melvin Conway, programista, hacker i wykładowca, powiedział w 1967 roku że „Każda organizacja projektująca (szeroko definiowany) system stworzy projekt, którego struktura jest kopią struktury komunikacyjnej organizacji”. To powiedzenie jest do dziś znane jako prawo Conway’a.

Czym jest architektura oprogramowania?

Architektura oprogramowania klasycznie opierała się na architekturze w tradycyjnym znaczeniu tego słowa. Architekt planował, jak cały system będzie wyglądał, dzielił całość na podsystemy, a następnie wyszkoleni eksperci zajmowali się wytwarzaniem swoich części danych podsystemów.

Gdy całość była gotowa, następowała kontrola jakości i oddanie systemu do użytkowania. W ten sposób funkcjonują projekty IT zarządzane w stylu waterfall.

Ponieważ analogie często działają tylko powierzchownie, szybko okazało się że budowanie oprogramowania nie ma tak wiele wspólnego z budowaniem katedr jak się wydawało.

Budynki z kamienia, drewna i stali zwykle stawia się w stabilnym otoczeniu. Materiały wykorzystane do budowy są wytrzymałe na zużycie. Użytkownicy tych budynków zdają sobie sprawę z kosztów, jakie pociąga za sobą każda przeróbka i nie proszą architekta i wykonawców o przebudowę co kilka miesięcy.

Dokładnie odwrotnie jest z oprogramowaniem. Otoczenie jest niestabilne, materiały rzadko kiedy mają długą gwarancję, a użytkownicy wiedząc, że zmiany są relatywnie tanie, bardzo często domagają się zmian. Na domiar złego, konkurencja na rynku może przyspieszać wymuszanie tych zmian oferując podobne produkty o pewnych dodatkowych funkcjach.

Świat (biznesowy) się zmienia

Odpowiedzią na ten brak stabilności są metodyki zwinnego zarządzania projektami, które zaczęły się pojawiać na początku XXI wieku.

Programowym odpowiednikiem katedr są tak zwane monolity. Aplikacje projektowane jako spójna całość, w której wszystkie podsystemy są sztywno ze sobą połączone.

Wprowadzenie zmian w jednym podsystemie wymaga przebudowania całości, a co za tym idzie dodatkowych testów, audytów bezpieczeństwa, oraz kooperacji wielu osób.

Ze względu na wysokie koszty i ryzyko takich działań, monolity bywają aktualizowane relatywnie rzadko.

Metodyki zwinne przesuwają obiekt naszych zainteresowań z gotowych produktów na potrzeby użytkowników i funkcje, które dostarcza im produkt. Celem jest szybko reagować na potrzeby rynku i dostarczać jakościowe rozwiązania wtedy, gdy klient ich potrzebuje, a nie raz do roku podczas aktualizacji.

W odpowiedzi na to, zamiast zespołów odpowiedzialnych za poszczególne etapy realizacji procesu wydawniczego (wytwarzanie oprogramowania, testowanie, audyty bezpieczeństwa, wdrożenie) mamy do czynienia z zespołami odpowiedzialnymi za poszczególne cechy produktu. Takie niezależne zespoły mogą wprowadzać swoje zmiany z różną szybkością. W jaki sposób więc skoordynować wydania produktu tak, by wszystkie te zmiany połączyć?

Tu właśnie możemy zaobserwować działanie prawa Conway’a. By zapewnić niezależność zespołów warto skupić się na niezależności podsystemów, które te zespoły wytwarzają.

W ten sposób sztywne połączenia ustępują miejsca połączeniom bardziej elastycznym. Zmiany w podsystemie obsługi podcastów nie wpływają na zmiany w pozostałych podsystemach. Każdy podsystem można testować i poddawać audytowi osobno. Testy integracyjne zapewniają, że po wdrożeniu takiego zaktualizowanego podsystemu, pozostałe podsystemy w żaden sposób nie odczują tej zmiany.

Oto mikrousługi

Taką kolekcję niezależnych od siebie w dużej mierze podsystemów nazywamy właśnie mikrousługami. Zamiast wytwarzać cały odbiornik radiowy, wytwarzamy poszczególne komponenty, które na ten odbiornik się składają: osobny system kontroli głośności, osobny dla fal krótkich, osobny dla fal długich, osobny odpowiedzialny za zapamiętywanie częstotliwości.

Mikrousługi są lepiej dostosowane do zwinnie rozwijanego oprogramowania. Pozwalają na niezależność zespołów pracujących nad poszczególnymi funkcjami systemu. Umożliwiają wybór odpowiednich metod i narzędzi do rozwiązania danego problemu. Integracje i wdrożenia można przeprowadzać częściej, co pozwala otrzymywać więcej informacji zwrotnych od klientów.

O powyższych zaletach mikrousług możemy usłyszeć dosyć często, rzadziej niestety wspomina się o ich kosztach. Rozwijanie mikrousług wymaga sporego narzutu organizacyjnego. Jeśli przy monolicie wystarczą dwie osoby odpowiedzialne za zapewnianie jakości (Quality Assurance – QA) to przy mikrousługach każdy zespół projektowy będzie potrzebował przynajmniej jednej osoby zajmującej się zapewnieniem jakości. Podobnie z każdą inną specjalizacją, która bierze udział w procesie rozwoju oprogramowania.

Jeśli dodamy do tego fakt, że każdy zespół może używać zupełnie innych narzędzi, może okazać się, że otrzymamy silosy kompetencji. Członkowie poszczególnych zespołów projektowych nie będą w stanie pracować nad żadnym innym projektem bez odpowiedniego przeszkolenia. Jeśli kilka osób odejdzie z zespołu w tym samym czasie, może się zdarzyć, że w całej firmie nikt nie wie jak działa dany podsystem!

Narzut występuje również na poziomie technicznym: niezależne usługi wymagają zwykle większych zasobów oraz więcej pasma poświęconego na komunikację.

Miałem okazję współpracować z firmą, która utrzymywała kilkadziesiąt mikrousług. Każda z nich była pisana korzystając z różnych standardów, różnych systemów budowania, różnych języków programowania. Gdy trzeba było szukać przyczyn nieoczekiwanych zachowań w kilku z nich, sprawa stawała się co najmniej ciekawa. Firma zresztą nie miała kilkudziesięciu zespołów projektowych, cały dział rozwoju oprogramowania miał mniej pracowników niż wynosiła liczba mikrousług. Niektóre z nich potrafiły więc być dość zaniedbane.

Kiedy zdecydować się na mikrousługi?

Czy zatem warto przestawić się na mikrousługi? By znaleźć odpowiedź na to pytanie trzeba zastanowić się nie tyle nad kwestiami technicznymi projektu, co nad strukturą jego organizacji. Odgórny przykaz „piszmy teraz mikrousługi”, który nie bierze pod uwagę zmian organizacyjnych, może skończyć się katastrofą o wiele gorszą niż klasyczny monolit.

Jeśli praktyki z pracy nad monolitem przeniesiemy do budowania systemu rozproszonego to, co otrzymamy, nie będzie w żadnym stopniu mikrousługami. Dostaniemy tak zwany rozproszony monolit, który łączy w sobie najgorsze cechy z obu podejść. Jest to system, który wykazuje cechy systemu rozproszonego, jednak jego komponenty są na tyle ściśle ze sobą powiązane, że wymagana jest ich skoordynowana aktualizacja. Nie dość, że narzut techniczny zwiększy koszty utrzymania takiego systemu, to konieczność synchronizacji wydań sprawi, że nie uzyskamy żadnych korzyści związanych ze zwinnością.

Tu wracamy do tematu naśladownictwa. Najwięksi gracze na rynku nie mają problemu z tym, by zatrudnić ekspertów o wielu różnych kompetencjach. Narzut organizacyjny również nie jest im straszny, bo są w stanie sobie na to pozwolić. Przy pewnej skali działań wymienione ograniczenia przestają mieć dominujące znaczenie. Częstsze wydania i zbieranie informacji zwrotnej z wielu testów pozwala im lepiej dostosować produkt do wymagań rynku, a przez to zwiększyć dochody.

Jeśli jednak nie pracujesz dla technologicznego giganta, to wspomniane ograniczenia mikrousług będą mocno dawać Ci się we znaki. Rozbijanie monolitów warto zacząć od zmian w strukturach organizacji. Zamiast przechodzić od razu do rozproszonych mikrousług, można skupić się na lepszym oddzieleniu istniejących podsystemów w obrębie istniejącego monolitu. Gdy okaże się, że można je wydzielić, będzie to dobry moment by pomyśleć o osobnych mikrousługach.

Warto uczyć się od innych i obserwować trendy. Zanim jednak zaczniemy naśladować Google, Spotify, czy Netflix zastanówmy się, czy rozwiązujemy takie same problemy jak oni. Rozwiązania rodem z Formuły 1 mogą robić wrażenie, ale wątpię czy przyniosą pozytywne rezultaty, jeśli zastosujemy je podczas jazdy po mieście.

Powyższe refleksje to wgląd w jeden z tematów przewodnich tegorocznej edycji AgileByExample, największej konferencji w Polsce dotyczącej zwinnych technik zarządzania.
W tym roku prelegenci i uczestnicy AgileByExample będą przyglądać się zjawiskom wpływającym na rolę agile w developmencie – czy i jak agile pomaga developerom w pracy? Jak pogodzić perspektywy Product Ownerów i Project Managerów? Jak wprowadzać agile w globalnie zarządzanych zespołach? Jak radzić sobie wobec nagłych, niespodziewanych i mających ogromne konsekwencje ogólnoświatowych wydarzeń, tzw. black swans?
Wśród tegorocznych keynote speakerów znaleźli się Janet Gregory, Jeff Liker, Roman Pichler i Geoff Watts. Ci i wielu innych inspirujących trenerów i praktyków agile będzie czekać na Was już 11-13 października, by podzielić się doświadczeniami i dobrymi praktykami. Jednym z nich będzie Piotr Gaczkowski, autor powyższego artykułu, którego wystąpienie “Microservices vs Monoliths” będzie można obejrzeć i wysłuchać 12 października. Szczegóły można znaleźć na agilebyexample.com