Architektura sterowana zdarzeniami to kolejny wpis z mini-serii blogów o architekturach aplikacyjnych. W pierwszym wpisie mogłeś przeczytać o architekturze warstwowej (wpis znajdziesz tutaj) a dziś na tapet bierzemy architekturę sterowaną zdarzeniami.
Cześć
O zdarzeniach mówi się sporo. Ostatnimi latami są one popularyzowane a czasami co nieco przekoloryzowane. W architekturze jest tak, że nie ma jednego złotego grala na rozwiązanie wszystkich problemów. Z pewnością architektura sterowana zdarzeniami sprwadza się przy pewnych problemach natomiast wpychana na siłę w każdy projekt jest drogą do porażki. Jako odpowiedzialni developerzy nie chcemy uprawiać CV-Driven-Development, zamiast tego świadomie wybieramy to co potrzebne.
Chcę żebyś po przeczytaniu tego artykułu znał zalety i wady podjętej decyzji, zobaczył realny przykład użycia architektury (tak żebyś mógł to sobie lepiej zobrazować) i mógł podjąć świadomą decyzję o wyborze architektury.
W dzisiejszym artykule:
Czym jest architektura sterowana zdarzeniami
Aby odpowiedzieć na pytanie czym w ogóle jest architektura sterowana zdarzeniami (Event-Driven Architecture / EDA) należy zdefiniować pojęcie zdarzenia.
Zdarzenie jest zmianą stanu aplikacji, która już nastąpiła. Zdarzenie jest niezmienne i nie możemy go cofnąć. Zdarzenia mogą być rozumiane jako wiadomości przesyłane pomiędzy różnymi modułami systemu.
W praktyce zdarzenia są wyzwalaczami (triggerami) pewnych zachowań w systemie. Samo zdarzenie nie jest świadome kto z niego korzysta. Zdarzenia są tworzone przez tzw. producentów (normalny serwis tylko produkujący zdarzenia) i przesyłane są do szyny zdarzeń (jakiś message broker, np. RabbitMQ czy Apache Kafka). Szyna odpowiednio filtruje i wypuszcza zdarzenia dalej do konsumentów. Konsumentem może być każdy. Może to być na przykład jakiś kolejny serwis będący producentem dla innego zdarzenia.
Architektura oparta na zdarzeniach posiada niski coupling (jest luźno powiązana), ponieważ producenci zdarzeń nie są świadomi którzy konsumenci ich nasłuchują (nawet nie wiedzą czy ktokolwiek nasłuchuje), a samo zdarzenie nie wie, jakie są konsekwencje jego wystąpienia. Jest to z pewnością jedna z dużych zalet bo w praktyce oznacza to, że możemy dołączać nowych producentów i konsumentów w optymalny sposób (nie jest to tak trywialne jak by się mogło wydawać).
A więc w prostych słowach jak można zdefiniować EDA? Jest to architektura reagująca na zdarzenia w systemie. Zdarzenia mogą być wewnętrzne (np. dodano produkt do zamówienia) lub zewnętrzne (np. pomiary z czujnika parkowania w samochodzie). Zdarzenia są tworzone przez producentów a ich odbiorcami są konsumenci. Każde zdarzenie przechodzi przez szynę zdarzeń (niektórzy nazywają to również kanałem zdarzeń – ang. event channel), ta natomiast jest implementowana głównie przy użyciu topologii mediatora lub brokera.
Topologia: Mediator vs Broker
Topologia mediatora jest używana kiedy zdarzenia składają się z kilku kroków i potrzebują pewnego rodzaju koordynacji do prawidłowego przetworzenia. Najlepiej przedstawić to na przykładzie.
Kupujesz bilet do kina. Wybrałeś seans, miejsce, przekąski i dokonujesz zapłaty. System w tym momencie wysyła na kolejkę zdarzenie: Kupiono bilet (miejsce: 3A, seans: Straszny film, sala: 6, czasRozpoczęcia: 17:00, itp.). Zdarzenie to jest wysyłane na kolejkę, która przekazuje je do mediatora (szyna koordynująca). Mediator następnie wysyła ’nowe’ zdarzenia na poszczególne kanały. W naszym przypadku będą to trzy nowe zdarzenia uruchomione asynchronicznie: Zarezerwuj bilet, Zarezerwuj miejsce na sali oraz Zaktualizuj liczbę odwiedzających. Kiedy zdarzenia się powiodą, mediator wysyła jeszcze jedno zdarzenie: Wyślij powiadomienie o pomyślnej rezerwacji.
Każde ze zdarzeń produkowanych przez mediatora jest przetwarzana przez tzw. event processor. Warto zauważyć, że takich procesorów dla konkretnego zdarzenia możemy podpiąć wiele. Jest to duża zaleta dla systemów, które potrzebują wysokiej dostępności.
Topologię brokera stosuje się natomiast kiedy produkowane zdarzenie nie jest zbyt skomplikowane i nie wymaga orkiestracji. Tak właściwie to przykład z góry nawet lepiej komponuje się właśnie do topologi brokera.
Wysyłane jest zdarzenie Kupiono bilet (miejsce: 3A, seans: Straszny film, sala: 6, czasRozpoczęcia: 17:00, itp.), które trafia na kanał Rezerwacji. Kanał ten produkuje nowe zdarzenie Zarezerwuj bilet. Na zdarzenie rezerwacji biletu nasłuchują dwa kolejne kanały rezerwacja miejsca (Zarezerwuj miejsce na sali) oraz aktualizacja odwiedzających (Zaktualizuj liczbę odwiedzających). Rezerwacja miejsca wysyła nowe zdarzenie Zarezerwuj miejsce na sali które trafia na kanał powiadomień (Wyślij powiadomienie o pomyślnej rezerwacji).
Jeżeli dalej masz problem ze zrozumieniem bo kiepowato to wytłumaczyłem (to jest prawdopodobne) to zajrzyj do tej książki (dostęp online dzięki oreilly).
Wady i zalety architektury
Jak już wiesz (lub właśnie się dowiesz) każda architektura rozwiązuje problemy z pewnych kategorii. Kategorie te są często definiowane przez drivery architektoniczne (np. szybkość developmentu, niezawodność platformy, bezpieczeństwo, itp.). Nie ma rozwiązania uniwersalnego i tak samo jest z architekturą sterowaną zdarzeniami.
Zaletami architektury sterowanej zdarzeniami są:
- Skalowalność i niezawodność – serwisy są świadome istnienia tylko szyny zdarzeń. Oznacza to, że możemy dodawać wiele serwisów i w przypadku awarii jednego z nich, inne będą działać dalej.
- Wydajność – operację mogą być wykonywane asynchronicznie.
- Zwinność – dzięki temu, że komponenty mają luźny coupling można dodawać nowe lub usuwać stare bez większych obaw, że coś się zepsuje.
Natomiast do wad należą:
- Development – należy rozumieć i umieć programować asynchroniczne.
- Testowalność – wymaga specjalnych narzędzi do generowania zdarzeń oraz kontraktów pomiędzy różnymi serwisami. Dodatkowo, natura architektury (asynchroniczność) jest także problematyczna, np. nie zawsze dostajemy zdarzenia w tej samej kolejności.
Podsumowanie
Przy użyciu architektury sterowanej zdarzeniami system może reagować na zmiany w czasie rzeczywistym. Analizując zdarzenia w systemie (które są dostarczane na bieżąco) biznes jest w stanie podejmować decyzje szybciej i dokładniej. Jest to napewno jeden z driverów architektonicznych jakie należy brać pod uwagę wybierając architekturę systemu.
EDA jest skomplikowanym wzorcem architektonicznym dlatego istnieje kilka wzorców projektowych pozwalających osiągnąć taką architekturę, są to m.in: Notification Pattern, Event-Carried State Transfer (ECST), Event Sourcing (ES), CQRS. Więcej na temat możesz przeczytaj u Martina Fowlera lub w tym artykule na medium.
Innym plusem EDA jest to, że pozwala na dostarczanie featerów bez modyfikacji i zajmowania czasu zespołowi, który jest odpowiedzialny za usługę produkującą zdarzenia. Wystarczy raz coś napisać i później wysyłać zdarzenia. Jeżeli ktoś będzie chciał zareagować na to zdarzenie to po prostu dodaje akcję (konsumenta). Nie tracimy wtedy czasu na komunikację i dostosowywanie konkretnych usług – po prostu mamy wystawiony pewien kontrakt i jak ktoś chce się dostosować to to robi.
Źródła:
- GOTO 2017 • The Many Meanings of Event-Driven Architecture • Martin Fowler
- Software Architecture Patterns (Mark Richards) – Chapter 2. Event-Driven Architecture
- EVENT DRIVEN ARCHITECTURE
- The importance of event-driven architecture in the digital world
Za tydzień
Chcę napisać coś osobistego – całkowicie niezwiązanego z programowaniem. Dawno takiego wpisu nie miałem a czuję że tego potrzebuję. Wpis będzie poświęcony ustawianiu celów i ich wartości w życiu.
Fajny artykuł, dzięki!. Do minusów można też dodać, że w przypadku gdy padnie szyna pada wszystko, lub też że szyna może zostać zapchana zdarzeniami delikatnie mówiąc nie posiadającymi najwyższego priorytetu, a to jedno ważne zdarzenie może sobie czekać w nieskończoność 🙂 Tak BTW, fajny blog, dzisiaj na niego wpadłem przekierowany z jvm-bloggers. Czekam na kolejne wpisy, pozdrawiam 🙂