Muszę napisać menedżera systemu powiadomień.
Oto moje wymagania:
Muszę być w stanie wysłać powiadomienie na różnych platformach, które mogą być zupełnie inne (na przykład muszę mieć możliwość wysłania wiadomości SMS lub e-mail).
Czasami powiadomienie może być takie samo dla wszystkich odbiorców na danej platformie, ale czasami może to być powiadomienie na odbiorców (lub kilku) na platformę.
Każde powiadomienie może zawierać ładunek specyficzny dla platformy (na przykład wiadomość MMS może zawierać dźwięk lub obraz).
System musi być skalowalny , muszę być w stanie wysłać bardzo dużą liczbę powiadomień bez awarii aplikacji lub serwera.
Jest to proces dwuetapowy. Najpierw klient może wpisać wiadomość i wybrać platformę, na którą ma zostać wysłany, a powiadomienia należy utworzyć w celu przetworzenia w czasie rzeczywistym albo później.
Następnie system musi wysłać powiadomienie do dostawcy platformy.
Na razie jednak mam kilka, ale nie wiem, jak będzie skalowalny lub czy to dobry projekt.
Myślałem o następujących obiektach (w pseudo języku):
Notification
obiekt ogólny :
class Notification {
String $message;
Payload $payload;
Collection<Recipient> $recipients;
}
Problem z następującymi obiektami polega na tym, że mam 1.000.000 odbiorców? Nawet jeśli Recipient
obiekt jest bardzo mały, zajmie zbyt dużo pamięci.
Mógłbym również utworzyć jedno powiadomienie dla odbiorcy, ale niektórzy dostawcy platformy wymagają ode mnie wysyłania go partiami, co oznacza, że muszę zdefiniować jedno powiadomienie z kilkoma odbiorcami.
Każde utworzone powiadomienie może być przechowywane w trwałym magazynie, takim jak DB lub Redis.
Czy dobrze byłoby agregować to później, aby upewnić się, że jest skalowalne?
Na drugim etapie muszę przetworzyć to powiadomienie.
Ale jak mogę odróżnić powiadomienie od odpowiedniego dostawcy platformy?
Czy powinienem użyć obiektu takiego jak MMSNotification
rozszerzenie abstract Notification
? czy coś w tym stylu Notification.setType('MMS')
?
Myślę, że aby umożliwić przetwarzanie wielu powiadomień w tym samym czasie, system kolejki przesyłania wiadomości, taki jak RabbitMQ, może być właściwym narzędziem. Czy to jest
Pozwoliłoby mi to ustawić w kolejce wiele powiadomień i umożliwić kilku pracownikom wyskakiwanie powiadomień i ich przetwarzanie. Ale co, jeśli będę musiał wysyłać odbiorców, jak pokazano powyżej?
Potem wyobrażam sobie, że NotificationProcessor
obiekt, do którego mógłbym dodać NotificationHandler
każdy, NotificationHandler
byłby odpowiedzialny za połączenie dostawcy platformy i wykonanie powiadomienia.
Mogę również użyć, EventManager
aby umożliwić zachowanie wtykowe.
Wszelkie informacje zwrotne lub pomysły?
Dziękuję za poświęcony czas.
Uwaga: Jestem przyzwyczajony do pracy w PHP i jest to prawdopodobnie wybrany przeze mnie język.
Edycja (zgodnie z odpowiedzią morphunreal)
- Ile wiadomości na sekundę wysyłasz (Zdefiniuj poziomy bieżący / początkowy, określ maksymalny poziom, który system powinien obsługiwać przed przeprojektowaniem)
- Jakie ograniczenia sprzętowe ma system (pamięć, procesor itp. Dostępne dla systemu)
- Jak skaluje się sprzęt (tj. Dodając więcej serwerów, przetwarzanie w chmurze itp.)
- W jakich językach / systemach będą generowane powiadomienia?
To sam, jestem odpowiedzialny za programowe tworzenie powiadomień, ale zbudowane z interfejsu użytkownika.
- Czy generator zna odbiorców wiadomości (?), Czy są udostępniane w inny sposób (np. Reguły biznesowe dla niektórych typów alertów są kierowane do niektórych odbiorców)
Powinno być możliwe utworzenie powiadomienia dla określonych odbiorców, grupy odbiorców (na przykład za pomocą systemu tagów) lub dla całej platformy.
- Czy istnieją reguły biznesowe dotyczące dodawania rachunków CC / BCC / Read
Tak. Zauważ, że jest to naprawdę specyficzne dla platformy i odczyt lub DW nie są dostępne na wszystkich platformach.
- Czy generator zna typ wiadomości, którą wysyła (tj. SMS / e-mail), czy też jest oparty na odbiorcy?
Opiera się on na odbiorcy, jednak ponieważ odbiorca jest powiązany z platformą, a platformy mają inny sposób obsługi danych, interfejs użytkownika prawdopodobnie będzie specyficzny dla platformy, umożliwiając konfigurację obrazów, dźwięku lub czegoś takiego.
- Czy generator wymaga potwierdzenia wysyłania / odbierania / odczytu wiadomości (asynchroniczne vs wysyłanie synchroniczne)
Cóż, system powinien być podatny na błędy, ale chcielibyśmy obsłużyć błąd w celu zdefiniowania zestawu reguł, na przykład jeśli serwer jest nieosiągalny, powiadomienie powinno być wymagane do dalszego przetwarzania, ale jeśli powiadomienie jest nieprawidłowe (lub zostało zdefiniowane przez dostawcę platformy) nie należy tego wymagać, ale powiadamiać.
- Czy istnieją wymagania dotyczące przechowywania historii źródeł / odbiorców wiadomości (jak długo?)
Tak, prawdopodobnie chcemy stworzyć statystyki i raporty. * Zdefiniuj punkty końcowe powiadomień
Jakie usługi są używane do wysyłania wiadomości? Zależy, niektóre są klasyczną usługą REST, inne są jakimś egzotycznym protokołem, to naprawdę zależy od dostawcy.
Jakie informacje zwrotne / potwierdzenia są przekazywane (synchronizacja / asynchronizacja)
Zależy, niektóre są zsynchronizowane i odpowiadają z błędem, podczas gdy inne muszą zostać pociągnięte, aby sprawdzić błędy.
- Czy to możliwe, aby dodać nowe punkty końcowe [nawet jeśli tak, to czy to nawet wymaga abstrakcji]
Tak, właściwie nasza aplikacja rośnie i prawdopodobnie chcemy dodać nowego dostawcę, ale jest to stosunek około 1 lub 2 rocznie.
Odpowiedzi:
Zacznij od oddzielenia wymagań funkcjonalnych i niefunkcjonalnych i dokładnego ich zdefiniowania. Bardzo łatwo jest przeprojektować system oparty na niejednoznacznych wymaganiach.
Na przykład Twoje niefunkcjonalne wymagania dotyczące skalowalności są dość niejednoznaczne. Może zmniejszyć obciążenie psychiczne, jeśli umieścisz rzeczywiste liczby w systemie. Na przykład,
Teraz, gdy masz to na uwadze, możesz skonfigurować kilka testów, aby upewnić się, że projekt / architektura systemu jest w stanie spełnić Twoje niefunkcjonalne wymagania.
Jeśli chodzi o biznesowe / funkcjonalne wymagania dotyczące wysyłania powiadomień / wiadomości, pomocne mogą być następujące wskazówki (jeśli podasz więcej informacji, mogę dodać do tej odpowiedzi):
Zdefiniuj źródła powiadomień
Zdefiniuj punkty końcowe powiadomień
Waham się, czy podać konkretny przykład architektury, ponieważ byłby on w dużej mierze zależny od czynników; ale często najprostsze systemy komunikatów obejmują podstawową kolejkę, albo w pamięci / aplikacji, bez SQL, na dysku lub w relacyjnej bazie danych. Następnie osobny proces (lub kilka oddzielnych procesów, jeśli są rozproszone) może sondować kolejkę pod kątem typów komunikatów [tj. Zadanie cron]; i wysłać w razie potrzeby.
Można to również ulepszyć za pomocą niektórych technik opartych na wypychaniu (tj. NOTGY / LISTEN PostgreSQL), jeśli istnieje konieczność natychmiastowego wysłania wiadomości.
Zaletą prostej kolejki jest to, że system generujący komunikat ma niewiele do zrobienia, a system przetwarzania może być zrównoważony w oparciu o wymagania sprzętowe / wydajnościowe.
źródło
Czy bierzesz pod uwagę wzorzec projektowy wagi latania dla obiektów powiadomień? Nie jestem tego zbyt pewny, ponieważ nigdy nie wdrożyłem wzoru, ale przypominam sobie, że wiąże się to z dzieleniem pewnego stanu między obiektami typu flyweight. Myślę też, że członkowie z większą redundancją mieli większy wpływ, jeśli zostali podzieleni. Zależy to więc od wysłania kilku wiadomości do wielu osób lub odwrotnie.
źródło