fbpx
5 min. czytania

Technologia stojąca za Ordering Stack

Dowiedz się, jaka technologia stoi za platformą Ordering Stack, jak jest zbudowana i jak działa. Najnowocześniejsza i stabilna technologia gwarantuje ciągłość usługi.

Technology Ordering Stack

Główna koncepcja

Ordering Stack to platforma e-commerce i pos dla sieci restauracji.

Składa się ona z usług backendowych oraz aplikacji frontendowych. Istnieją usługi uwierzytelniania, produktów i menu, miejsc, płatności, zamówień i inne, dostarczające funkcjonalności biznesowe dla poszczególnych domen biznesowych systemu. Każda z nich eksponuje swoje własne REST API. Aby uzyskać dostęp do którejkolwiek z tych usług, klienci muszą najpierw uzyskać tokeny dostępu z usługi uwierzytelniajacych. Mając taki token, klienci mogą wywoływać punkty końcowe API podając dane uwierzytelniające w nagłówku żądania.

Oprócz wywoływania API, klienci będą otrzymywać asynchroniczne wiadomości z backendu poprzez websockets. Wiadomości te zawierają stan zamówień i inne powiadomienia.

Ogólna idea pracy z backendem polega na wywoływaniu metod API i odbieraniu aktualizacji stanu przez websocket. Aplikacje klienckie muszą być przygotowane do pracy asynchronicznej.

Przegląd Architektury

  • nieblokujący i asynchroniczny

polecenia użytkownika i aktualizacje są przesyłane dwoma niezależnymi kanałami HTTP Request i WebSokets

  • działa jak gry online dla wielu graczy (MMOG)

cały stan jest utrzymywany po stronie serwera

użytkownicy wysyłają komendy do serwera bez czekania na wykonanie akcji (otrzymują tylko potwierdzenie pomyślnego umieszczenia w kolejce)

zaktualizowany stan jest dostarczany asynchronicznie

Opis użycia API i websocket można znaleźć tutaj: https://docs.orderingstack.com/api-examples/

Obecnie wszystkie nasze aplikacje klienckie są realizowane jako aplikacje React.js.

Jak robiony jest backend

Podczas dyskusji nad architekturą Ordering Stack chcieliśmy kierować się zasadami DDD (Domain Driven Design) i zamykać poszczególne obszary biznesowe w osobnych (mikro)usługach. Każda usługa w ramach domeny powinna być również luźno sprzężona z innymi usługami, nie wywołując zbyt często ich API w zakresie pobierania danych spoza ograniczonego kontekstu.

Kolejną rzeczą było zaimplementowanie asynchronicznego procesu przepływu zamówień z przychodzącymi komendami z API zamówień i odsyłaniem powiadomień przez websockety. Musieliśmy choreografować wiele usług w miarę wykonywania kolejnych etapów przetwarzania zamówienia. Do tego celu wykorzystaliśmy platformę event streamingową.  

Można to sobie wyobrazić w ten sposób:

Technology Ordering Stack
Diagram przedstawiający Apache Kafka i wiele usług jako wydawcy i subskrybenci

Należy pamiętać, że platforma brokera komunikatów (event streaming) jest centralnym szkieletem całego systemu. Po pierwsze pomaga ona w wymianie danych pomiędzy usługami, co pozwala uniknąć zbyt dużej interakcji pomiędzy nimi. Każdy mikroserwis może utrzymywać własne dane, w tym te należące do innych serwisów i aktualizować je w miarę napływu odpowiednich zdarzeń. Po drugie, umożliwia choreografię usług, gdyż mogą one reagować na przychodzące zdarzenia i publikować inne zdarzenia w celu aktywowania innych usług. Takie podejście sprawia, że całe rozwiązanie jest znacznie bardziej zwinne, wydajne (nieblokujące), odporne na awarie i wytrzymałe. Jako przykład korzyści, mogliśmy w prosty sposób dodać wsparcie dla webhooków w procesie przetwarzania zamówień.

Z punktu widzenia implementacji wykorzystaliśmy następujące technologie:

  • mikroserwisy budowane są przy użyciu Javy, Spring boot lub node.js,
  • mongodb jest używany, jeśli usługa potrzebuje przechowywania danych (usługi nie mogą współdzielić baz danych).
  • mikroserwis używa wykrywania usług do wyszukiwania innych usług (Eureka)
  • każda mikrousługa jest uruchomiona w kontenerze Docker (docker compose używany do orkiestracji kontenerów)
  • Apache Kafka jest wykorzystywana jako platforma do strumieniowania zdarzeń

Wielodostępność

Ordering Stack jest platformą SaaS w chmurze i może być wykorzystywany przez wielu klientów (najemców).  Każda mikrousługa w systemie obsługuje multi-tenancy. Identyfikatory najemców są również zawsze zakodowane w tokenie dostępu. Jeśli usługa posiada swój własny magazyn (storage), to dane dla każdego najemcy są przechowywane w różnych kolekcjach. Również każdy najemca ma inne tematy do przetwarzania zleceń w platformie strumieniowania zdarzeń (Kafka).

Wydajność

Zamawianie żywności ma swoją własną charakterystykę wzorców użycia w ciągu tygodnia i godzin w ciągu dnia. Zazwyczaj występują szczyty zamówień w porze lunchu i wieczorami. [Poniedziałek jest zazwyczaj słaby, a piątek, sobota i niedziela są najsilniejsze. Dodatkowo warunki pogodowe mogą silnie wpływać na zamówienia w ciągu dnia, ulewny deszcz lub śnieg mogą znacząco zwiększyć liczbę zamówień. Wreszcie – wydarzenia marketingowe, takie jak precyzyjne reklamy czasowe lub specjalne dni, takie jak „międzynarodowy dzień pizzy” mogą odgrywać ogromną rolę w pozyskiwaniu nowych zamówień.

Biorąc pod uwagę wszystko powyższe, platforma do zamawiania musi być przygotowana na duże obciążenie. Dlatego projektując Ordering Stack postawiliśmy wydajność i skalowalność wysoko na liście naszych priorytetów. Chcieliśmy uniknąć jakichkolwiek menu i skomplikowanych obliczeń produktów podczas przetwarzania żądania, blokowania odpowiedzi z powodu przeliczania rabatów w koszyku i tak dalej. Tworząc ten system, niektóre logiki mogą być umieszczone poza rdzeniem systemu, jak webhooks, które mogą być przypisane swobodnie przez najemcę w jego konfiguracji. Nie mamy żadnej kontroli nad wydajnością takich elementów! Odpowiedzią jest asynchroniczność. Wszystkie akcje związane z zamówieniami jak np. dodanie produktu do koszyka wysyłane są do backendu jako komendy poprzez żądanie REST. Są one umieszczane w strumieniu kafka do dalszego przetwarzania przez wiele mikroserwisów w różnych domenach, takich jak weryfikacja menu, przetwarzanie zamówień, rabaty, lojalność itp. i kiedy nowy stan zamówienia jest gotowy, jest on wysyłany z powrotem do aplikacji zamawiającej przez websocket. Dodatkowo wszystkie zewnętrzne wywołania używają precyzyjnych timeoutów i wzorców wyłączników dla lepszej niezawodności.

Należy wspomnieć, że wszystkie mikroserwisy dołączone do Kafka Stream są bezstanowe i mogą być skalowane horyzontalnie w odniesieniu do architektury Kafka. Kafka gwarantuje kolejność przetwarzania zdarzeń nawet przy wielu instancjach przetwarzających. Jest to osiągane poprzez umieszczenie wszystkich zdarzeń związanych z jednym zamówieniem w tej samej partycji tematycznej, a każda partycja może być przetwarzana tylko przez jeden wątek (jest to założenie projektowe).

Wszystkie te techniki sprawiają, że Ordering Stack jest systemem o wysokiej wydajności i dostępności, zdolnym do obsługi nawet wysokich szczytów.

Środowisko testowe i produkcyjne

Do hostingu naszych rozwiązań wykorzystujemy sprawdzonych w boju dostawców usług hostingowych i chmurowych takich jak 3S i Microsoft Azure. Obecnie wszystkie serwery znajdują się na terenie Unii Europejskiej.

Większość artefaktów systemowych jest skonteneryzowana za pomocą Dockera, używamy gitlab dla CI/CD i innych usług do monitorowania jak wszystkie nasze środowiska działają.

Technologies logo

Zostańmy w kontakcie

Chcesz wiedzieć więcej? 
Uwielbiamy rozmawiać o technologii!

+48 725 935 000

[email protected]

New posts

Discover more from Ordering Stack

Subscribe now to keep reading and get access to the full archive.

Continue reading