Tworząc system o architekturze mikroserwisowej mamy do zbudowania skomplikowany system wzajemnych powiązań pojedynczych trybików wielkiej maszyny. Jednak trybik trybikowi nierówny. Mamy różne rodzaje mikroserwisów, każdy rządzi się innymi prawami i ograniczeniami.
Osobiście dzielę mikroserwisy na cztery kategorie:
- Biznesowe
- Agregacyjne
- Integracyjne
- Techniczne
Spójrzmy na nie.
Biznesowe
O tym rodzaju mikroserwisów prawdopodobnie myślisz w pierwszej kolejności. To jest ten „rzeczywisty” kod biznesowy. Tutaj powinny się znaleźć wszelkie operacje biznesowe, wszystkie komendy i akcje zmieniające stan systemu lub wyzwalające taką zmianę gdzie indziej. Takie właśnie usługi orkiestrują procesami biznesowymi, powołują je do życia i przetwarzają. Tak naprawdę tutaj ląduje 90% wymagań, jakie dostaniesz od biznesu.
O przykład takich usług nie trudno, np. mogą to być usługi odpowiedzialne za:
- artykuły,
- komentarze,
- użytkowników,
- tagi i kategorie.
Agregacyjne
Skoro już wiemy gdzie umieścić core naszego systemu, to pora przejść trochę dalej. Usługi agregacyjne to rodzaj mikroserwisów, których głównym celem jest optymalizacja i odciążenie usług biznesowych.
Mają one na celu zebranie danych z wielu źródeł i dostarczenie ich w formacie przetworzonym, bardziej przyjaznym dla odczytów. Usługi takie oczywiście mogą mieć własną bazę danych, która jest na bieżąco odświeżana danymi z usług biznesowych – na przykład na podstawie zdarzeń.
Ten typ usług można znaleźć we wzorcu CQRS, czyli Command Query Responsibility Segregation. Jest to wzorzec, w którym separujemy odpowiedzialność za logikę modyfikacji danych (Command) – czyli w naszym przypadku do mikroserwisów Biznesowych, od logiki odpowiedzialnej za odczyty (Query) – czyli do mikroserwisów Agregacyjnych.
Innym, często spotykanym, przypadkiem dla zastosowania tego rodzaju mikroserwisów są wszelkie raporty czy statystyki.
Kilka przykładów usług agregacyjnych:
- katalog produktów,
- lista artykułów,
- raporty.
Integracyjne
Kolejny rodzaj to mikroserwisy integracyjne. Ich zadaniem jest ułatwienie integracji innym usługom. Mogą służyć do stworzenia prostego API przykrywającego dużo bardziej skomplikowane. Mogą też zapewniać fasadę technologiczną. Na przykład w sytuacjach, w których musimy zintegrować się z systemem, którego API nie pasuje do założeń warstwy integracyjnej naszego systemu. W takim przypadku umiejscowienie całego kodu potrzebnego na tłumaczenie protokołów w jednym miejscu – w jednej usłudze, jest bardzo dobrym rozwiązaniem.
Podobnym przypadkiem jest sytuacja, kiedy format danych komunikatów innego systemu nie do końca odpowiada wymaganiom naszego API. Wtedy stworzenie specjalistycznego mikroserwisu, odpowiedzialnego tylko za komunikację między tymi dwoma systemami ma sens. API naszego systemu pozostaje bez zmian, a cały kod odpowiedzialny za dostosowanie formatu danych umieszczony jest w oddzielnym komponencie.
Przykłady użycia takich usług:
- API REST przykrywający usługi MQ,
- API JSON przykrywające usługi SOAP,
- fasada dla systemów legacy,
- konwersja formatu danych zdarzeń na Topikach Kafki (TOPIC.A -> TOPIC.B).
Techniczne
No i doszliśmy do ostatniego rodzaju mikroserwisów. Za techniczne usługi uważam wszystko to, co nie mieści się w powyższych kategoriach, a jest niezbędne do działania naszego systemu. Powodów może tutaj być wiele.
Mogą to być na przykład usługi zapewniające dostęp do konfiguracji – Spring Cloud Config Server. Może to być też API Gateway – Zuul. Jest to usługa, która wystawia API do naszego systemu i odpowiada za przepuszczanie ruchu do odpowiednich usług z wewnątrz. Wszelkie usługi zapewniające bezpieczeństwo, wydające tokeny autoryzacyjne itp. Przechowujące hasła jak na przykład Vault.
Do tego dochodzą jeszcze usługi odpowiedzialne za monitoring systemu, wliczając w to logi, metryki, czy śledzenie wywołań. Wszelkie narzędzia wspomagające procesy CI/CD, łącznie z Jenkinsem, Sonarem itp. Oczywiście nie jest to część naszego systemu, ale ma istotny wpływ na jego działanie pod względem szybkości reakcji na zaistniałe problemy.
Podsumowanie
Projektując system oparty na mikroserwisach, pamiętaj o tym rozróżnieniu. Każdy z tych rodzajów rządzi się innymi prawami. Ma inne wymagania co do niezawodności, inne metryki do monitorowania i odpowiedzialność za nie może leżeć w różnych działach IT. Samo rozdzielenie funkcjonalności pomiędzy kilka mikroserwisów, daje Ci możliwość niezależnego skalowania – co się przekłada na lepsze wykorzystanie zasobów. Nie mniej ważne jest też, żeby nie przesadzić. Każdy kolejny mikroserwis to dodatkowy narzut. Zwiększa poziom skomplikowania, koszt utrzymania oraz wpływa na wydajności na poziomie komunikacji między usługami – trzeba znaleźć złoty środek.