Obecna sytuacja
Wdrażamy (i obecnie utrzymujemy) aplikację internetową do zakupów online w architekturze mikrousług.
Jednym z wymagań jest to, że firma musi być w stanie stosować zasady dotyczące tego, co nasi klienci dodają do koszyka, w celu dostosowania ich doświadczenia i ostatecznego zamówienia. Z pewnością trzeba było wprowadzić silnik reguł biznesowych i wdrożyliśmy do tego specyficzną „mikrousługę” (jeśli nadal moglibyśmy to tak nazwać).
W ciągu roku ten silnik reguł stawał się coraz bardziej złożony, wymagając coraz większej ilości danych (np. Zawartości koszyka, ale także informacji o użytkowniku, jego roli, istniejących usługach, niektórych danych rozliczeniowych itp.), Aby móc obliczyć te reguły.
Na razie nasza shopping-cart
mikrousługa zbiera wszystkie te dane z innych mikrousług. Mimo że część tych danych jest używana przez shopping-cart
większość czasu, są one głównie wykorzystywane do zasilania silnika reguł.
Nowe wymagania
Teraz pojawia się potrzeba, aby inne aplikacje / mikrousługi ponownie wykorzystały silnik reguł do podobnych wymagań. W obecnej sytuacji musieliby zatem przesyłać ten sam rodzaj danych, wywoływać te same mikrousługi i budować (prawie) te same zasoby, aby móc wywołać silnik reguł.
Kontynuując, napotkamy kilka problemów:
- każdy (wywołujący silnik reguł) musi ponownie wdrożyć pobieranie danych, nawet jeśli nie potrzebuje ich dla siebie;
- żądania do silnika reguł są złożone;
- kontynuując w tym kierunku, będziemy musieli przetransportować te dane w całej sieci dla wielu żądań (pomyśl o μs A wywołującej μs B wywołującej silnik reguł, ale A ma już niektóre dane, których potrzebuje silnik reguł);
shopping-cart
stał się ogromny z powodu pobierania wszystkich danych;- Prawdopodobnie zapominam o wielu…
Co możemy zrobić, aby uniknąć tych problemów?
Idealnie byłoby uniknąć dodawania większej złożoności do silnika reguł. Musimy również upewnić się, że nie stanie się ono wąskim gardłem - na przykład niektóre dane są dość wolno pobierane (10 s lub nawet więcej), więc wdrożyliśmy wstępne pobieranie, shopping-cart
tak aby dane były bardziej prawdopodobne przed wywołaniem reguł silnik i zadbaj o komfort użytkowania.
Jakieś pomysły
- Pozwól, aby silnik reguł pobierał potrzebne dane. Zwiększyłoby to jeszcze bardziej złożoność, naruszając zasadę pojedynczej odpowiedzialności ( nawet więcej… );
- Zaimplementuj serwer proxy μs przed mechanizmem reguł, aby pobrać dane;
- Zaimplementuj „moduł pobierania danych” μs, który wywołuje silnik reguł, aby pobrać wszystkie potrzebne dane naraz (zapytanie złożone).
shopping-cart
, ale możemy dość łatwo dostosować go do potrzeb innych mikrousług (nadal są one związane z użytkownikami, produktami i zamówieniami). Jak widzimy, będą potrzebować tych samych danych wejściowych, zwłaszcza, że firma jest w stanie wybrać predykaty do zastosowania. Wszystkie dane są dostarczane przez inne mikrousługi z wyjątkiem samej zawartości koszyka. Pobieranie danych nie jest skomplikowane per se , ale staje się skomplikowana, kiedy trzeba zadzwonić ~ 10 innych microservices i utrzymać strukturę oczekiwanego przez silnik reguł.Odpowiedzi:
Cofnijmy się o sekundę i oceńmy nasze początkowe miejsce, zanim wypiszemy tę odpowiedź, która prawdopodobnie będzie nowością. Ty masz:
Ok, to nie jest tak świetne dla mikrousług. Natychmiast rażącym problemem jest to, że wydajecie się, że nie rozumiecie, czym są mikrousługi.
Musisz zdefiniować jakiś interfejs API lub metodę komunikacji, z której będą korzystać Twoje mikrousługi i aby były one powszechne. Może to być biblioteka, którą wszystkie mogą importować. Być może definiuje protokół wiadomości. Może używać istniejącego narzędzia ( poszukaj magistrali komunikatów mikrousług jako dobrego miejsca początkowego).
Kwestia komunikacji między służbami nie jest sama w sobie „rozwiązanym” problemem, ale w tym momencie nie jest też problemem „rzuć własnym”. Wiele istniejących narzędzi i strategii może ułatwić Ci życie.
Niezależnie od tego, co robisz, wybierz jeden system i spróbuj dostosować interfejsy API komunikacji, aby z niego korzystać. Bez określonego sposobu interakcji między usługami będziesz miał wszystkie wady mikrousług i usług monolitycznych i żadnej z nich.
Z tego wynika większość problemów.
Uczyń je mniej złożonymi.
Znajdź sposoby, aby uczynić je mniej złożonymi. Poważnie. Wspólne modele danych, podziel silnik pojedynczych reguł na mniejsze lub coś takiego. Spraw, aby silnik reguł działał lepiej. Nie bierz „zakleszczenia wszystkiego w zapytaniu i po prostu komplikuj je” - poważnie przyjrzyj się temu, co robisz i dlaczego.
Zdefiniuj protokół dla swoich danych. Moje przypuszczenie to macie nie określono planu API (zgodnie z powyższym) i zaczęli pisać REST wzywa ad hoc w razie potrzeby. To staje się coraz bardziej skomplikowane, ponieważ teraz musisz utrzymywać każdą mikrousługę za każdym razem, gdy coś zostanie zaktualizowane.
Co więcej, nie jesteś pierwszą firmą, która wdrożyła narzędzie do zakupów online. Idź zbadać inne firmy.
Co teraz...
Następnie co najmniej trzy najważniejsze problemy.
Kolejnym problemem jest to pytanie dotyczące silnika reguł. Mam nadzieję, że jest to dość bezpaństwowiec, dzięki czemu można go skalować. Jeśli tak, to chociaż nieoptymalne, przynajmniej nie umrzesz w blasku chwały ani nie zbudujesz szalonych obejść.
Chcesz, aby silnik reguł był bezstanowy. Ustaw tak, aby przetwarzał tylko dane. Jeśli okaże się, że jest to wąskie gardło, zrób to, abyś mógł uruchomić kilka serwerów proxy / modułu równoważenia obciążenia. Nie idealny, ale wciąż wykonalny.
Poświęć trochę czasu na zastanowienie się, czy któraś z twoich mikrousług naprawdę powinna zostać wprowadzona do silnika reguł. Jeśli tak znacznie zwiększasz obciążenie systemu, aby osiągnąć „architekturę mikrousług”, musisz poświęcić więcej czasu na planowanie tego.
Alternatywnie, czy silnik reguł można podzielić na części? Możesz zyskać, robiąc części swoich usług specyficznych dla silnika reguł.
Zakładając, że problem występuje po rozwiązaniu powyższych problemów, musisz poważnie zbadać, dlaczego tak się dzieje. Masz koszmar, który się rozwija, ale zamiast dowiedzieć się, dlaczego (10 sekund? Na przesłanie danych z portalu zakupowego ? Zadzwoń do mnie cynicznie, ale wydaje się to nieco absurdalne), wydajesz się raczej łatać objawy, niż patrzeć na problem powodujący objawy w pierwsze miejsce.
Używałeś wyrażenia „pobieranie danych” w kółko. Czy te dane są w bazie danych? Jeśli nie, zastanów się nad tym - jeśli spędzasz tyle czasu na „ręcznym” pobieraniu danych, wydaje się, że dobrym pomysłem byłoby użycie prawdziwej bazy danych.
Być może będziesz mógł mieć projekt z bazą danych dla pobieranych danych (w zależności od tego, co to jest, wspominałeś o tym wiele razy), kilkoma silnikami reguł i klientami.
Ostatnia uwaga: upewnij się, że używasz odpowiedniej wersji swoich interfejsów API i usług. Drobne wydanie nie powinno naruszać kompatybilności wstecznej. Jeśli uwolnisz wszystkie swoje usługi w tym samym czasie, aby działały, nie masz architektury mikrousług, masz rozproszoną architekturę monolityczną.
I ostatecznie, mikrousługi nie są rozwiązaniem uniwersalnym. Proszę, ze względu na wszystko, co święte, nie róbcie tego tylko dlatego, że jest to nowa modna rzecz.
źródło
Biorąc pod uwagę ilość informacji przedstawionych na temat silnika reguł oraz jego danych wejściowych i wyjściowych, myślę, że twoja sugestia nie. 2 jest na dobrej drodze.
Obecni konsumenci silnika reguł mogliby zlecić proces zbierania wymaganych informacji komponentowi bardziej specjalnego przeznaczenia.
Przykład: obecnie używasz silnika reguł do obliczania rabatów, które należy zastosować w odniesieniu do zawartości koszyka. Uwzględniają wcześniejsze zakupy, położenie geograficzne i aktualne oferty.
Nowym wymogiem jest wykorzystanie wielu tych samych informacji do wysyłania pocztą elektroniczną ofert do poprzednich klientów w oparciu o nadchodzące promocje i poprzednie zakupy. Uwzględniają poprzednie zakupy, aktualne i nadchodzące oferty.
Miałem do tego dwie osobne usługi. Każdy z nich polegałby na serwisie silnika reguł w zakresie niektórych ciężkich zadań podnoszenia. Każdy z nich zbierałby wymagane dane potrzebne do przesłania żądania do silnika reguł.
Mechanizm reguł po prostu stosuje reguły, konsumenci nie muszą się martwić o to, jakie dokładnie dane potrzebuje silnik reguł dla konkretnego kontekstu, a te nowe usługi pośredniczące robią tylko jedną rzecz: Zbierz kontekst i przekaż żądanie silnikowi reguł i zwraca odpowiedź niezmodyfikowaną.
źródło
Agregowanie danych wymaganych do podjęcia decyzji powinno odbywać się poza silnikiem reguł. Wynika to z tego, że najlepiej je zaprojektować jako usługi bezstanowe, o ile to możliwe. Pobieranie danych musi koniecznie obejmować przetwarzanie asynchroniczne i przechowywanie stanu. Nie ma większego znaczenia, czy pobieranie odbywa się przez serwer proxy na czele usługi decyzyjnej, przez osoby dzwoniące czy przez proces biznesowy.
Jako praktyczną kwestię do wdrożenia wspomnę, że IBM Operational Decision Manager zaczyna dokumentować i już obsługuje użycie produktu w kontenerach dokerów . Jestem pewien, że inne produkty również zapewniają to wsparcie i że zostanie ono włączone do głównego nurtu.
źródło
Wydaje mi się, że w moim prostym podejściu pomoże to wstępnie pobrać wszystkie wymagane dane, wykonując zestaw asynchronicznych wywołań do usług wyszukiwania danych, gdy tylko klient zacznie kupować i buforować dane. Kiedy więc musisz zadzwonić do serwisu reguł, dane już tam są. I nadal będą dostępne dla innych usług podczas sesji.
źródło