Obsługa i tworzenie menu - pod kątem restauracji.
Przeglądanie menu.
Tworzenie zamówienia.
Integracja z płatnością.
Podgląd zamówienia
Non-Functional Requirements:
Low latency (p99 < 500ms)
Real-time tracking (on map)
Scalability
High Availability
10 000 000 Zamowień dziennie
Pik ruchu - 20x średnia
Maksymalna ilość zamówień na sekundę to 2300 zamówień na sekundę.
Ilość danych w zamówieniu - zawiera ID restauracji (8B), lokalizację zamówienia (adres - 200B), pewnie średnio ze 4 posiłki, każdy zawiera ilość i ID (16B * 4 = 64B). Pewnie jedno zamówienie może mięć 300B.
Każda transakcja generuje 10 dodatkowych requestów - autoryzacja, odświeżanie, statusy).Przepustowość zamówień na sekundę - 2300 * 300B = 0.7MB. Dziennie dochodzi ok 60GB zamówień. Miesięcznie dochodzi 2TB.
Procesowanie jednego zamówienia - średnio pewnie 2h.
Odświeżanie statusu - pewnie średnio 10%.
Liczba odpytań o status zamówienia - co 10 sekund lub na żądanie.
Liczba restauracji - 50000, każde ma 50 pozycji w menu - 2 500 000.
Restaurant Service:
Orders Service:
Couriers Service:
Mamy dwa sposoby na komunikację się z systemem: przez aplikację mobilną (osobną dla restauracji, driverów oraz klientów) oraz przez aplikacje mobilne (również z podziałem).
Standardowo wszystkie requesty idą przez:
Restauracja:
Kurierzy:
Klienci:
Define the data model. Identify the main entities, their attributes, and relationships. Consider the choice of database type (SQL vs NoSQL) and justify your decision based on access patterns...
Dane restauracji powinny być cache'owane w największym stopniu. W przypadku ich braku - dane powinny być pobierane z bazy danych. Może to być baza danych dokumentowa - najbardziej odpowiednia do zapewnienia HA oraz do danych tekstowych.
Najważniejszym flow w systemie jest przetwarzanie zamówień.
Utworzenie zlecenia najpierw powinno być walidowane na podstawie aktualnych godzin pracy restauracji, danych dowozu.
Po pozytywnej walidacji, zamówienie jest zapisywane w bazie danych.
Następnie procesowana jest płatność - najpierw przekierowanie do jednego z dostawców płatności - żeby zapewnić HA w przypadku niedziałania jednego z nich.
Po otrzymaniu pozytywnej informacji o płatności, aktualizowany jest status zamówienia, jednocześnie w ramach Transaction Outbox Pattern jest zlecana wysyłka notyfikacji/websocket do aplikacji restauracji.
Restauracja potwierdza zamówienie lub odrzuca.
W przypadku odrzucenia zamówienia przez restaurację, zamówienie jest anulowane, notyfikacja jest wysyłana do klienta oraz zlecany jest zwrot płatności do klienta.
Jeśli zamówienie jest zaakceptowane, kolejne potwierdzenia są potrzebne: potwierdzenie gotowości oraz potwierdzenie wydania kurierowi.
Przy potwierdzeniu gotowości na kolejkę zamówień gotowych jest rejestrowane zdarzenie. To zdarzenie jest pobierane przez serwis przydzielający kurierów do zamówień. Jest to osobny serwis z własnym algorytmem.
Kurier jest informowany o zarejestrowanym zamówieniu. W momencie odbioru aktualizuje status na "przekazane kurierowi".
Skalowanie:
Baza danych zamówień najlepiej by była relacyjna i transakcyjna. Na podstawie danych lokalizacji można zastosować sharding - każde zlecenie ma prefix z id lokalizacji, który jednocześnie jest jego wirtualnym shardem. Określenie lokalizacji może być problematyczne w przypadku dużych miast lub całych aglomeracji.
Algorytm przypisywania zleceń kurierom powinien być wykonywany przez jedną instancję per shard. Aby zapewnić HA serwis może być replikowany, ale nieaktywny, jako że przetwarzanie powinno być wyłączne dla jednego consumera.
Shardowanie dotyczy zamówień, restauracji oraz kurierów.
Aktualizacja statusu zamówienia:
Każda aktualizacja wysyłą push/in-app notification, które aktywują aplikację, która pobiera najnowszy status zlecenia.
Statusy zleceń są cache'owane. Statusy są usuwane dopiero 1h po zakończeniu przetwarzania.