Od kilku lat prowadzę projekt po tytułem IoT Network. Jest to system do obsługi inteligentnych urządzeń. Wszystkie urządzenia, które wchodzą w jego skład można znaleźć w poprzednich wpisach na moim blogu. O samym systemie jeszcze nigdy nie pisałem tutaj, wiec myślę, że temat migracji to idealna sytuacja, aby to zmienić. Celem tej serii artykułów będzie przedstawienie jak wygląda system rozproszony i jakie są jego wady oraz zalety w utrzymywaniu i rozwijaniu przez jedną osobę. Opisze każdy etap migracji z mikroserwisów, poprzez monorepo (z dodatkiem), a kończąc na modularnym monolicie.
Plan brzmi następująco:
- Przeniesienie mikroserwisów do jednego repozytorium
- Jak ułatwić sobie życie z narzędziem NX?
- Połączenie mikroserwisów w jeden modularny monolit
- Worker’y – co to jest i jak działa
- Przejście z docker-compose na produkcji do Kubernetes
Stan aktualny
Backend składa się aktualnie z 4 mikroserwisów, z czego każdy komunikuje się z każdym w sposób synchroniczny za pomocą REST API albo asynchroniczny z użyciem RabbitMQ (w przypadku eventów). Ponadto prawie każdy mikroserwis posiada swoją bazę danych, czy to relacyjną MySQL, czy dokumentową (MongoDB). Jak widać na diagramie dostęp z publicznej sieci następuje tylko poprzez serwis o nazwie ApiGateway, w którym został zaimplementowany mechanizm uwierzytelniania.
Dlaczego decyzja o migracji?
Utrzymywanie mikroserwisów z biegiem czasu staje się coraz trudniejsze. Dochodzą nowe, co zwiększa ilość kodu oraz infrastruktury do utrzymania. Dodatkowo długo nieaktualizowane często po wejściu i chęci wprowadzenia zmian wymagają uprzednio zaktualizowania paczek, co nie zawsze jest takie proste. Wiem, że są narzędzia to ułatwiające, np. Renovate Bot, który sam wystawia Merge Request’a z aktualizacją paczek, ale wtedy i tak musimy w tylu miejscach ile jest mikroserwisów tego bota zaimplementować i dbać, żeby na każdym działał tak samo. Kolejną rzeczą jest duplikowanie sporej ilości kodu i tworzenia go pod „przelotkę” czyli, przekazanie zapytania głębiej w system przez ApiGateway. Sprawia to, że rozwój funkcjonalności wymaga w większości przypadków zmian w więcej niż jednym serwisie. Dodatkowo przy zapytaniach REST tracimy typowanie, no, chyba że zadbany o to, aby typy były osobną paczką i były współdzielone pomiędzy mikroserwisami, ale tu znowu sporo pracy i wysiłku. Infrastruktura też się kłania, bo zamiast deployować jedną aplikację, musimy wydawać często ich wiele i dbać, aby każda miała dobrze skonfigurowane połączenie.
Moim zdaniem w projektach indywidualnych nie ma sensu stosować mikroserwisów, no może poza celem edukacyjnym, albo na prawdę, kiedy mamy ku temu bardzo dobry argument, bo niestety w większości przypadków, będzie się to wiązało z dużo większym nakładem pracy za ten sam efekt co modularny monolit.