W niniejszym artykule przedstawiam etapy projektowe, dylematy techniczne a także zastrzeżenia i oczekiwania dotyczące zagadnień takich jak migracja do chmury publicznej wraz z jednoczesnym planem modernizacji aplikacji. Znajdziesz w nim także omówienie (czasami koniecznych) kompromisów, jakie firmy muszą podjąć stając przed wyzwaniami związanymi z takim podejściem.
Jest to pierwszy tekst z serii poświęconej tematowi: migracja do chmury i modernizacja aplikacji. Zapraszam do lektury!
Wprowadzenie
Proces zbierania i mapowania wymagań architektury przed migracją do chmury, przedstawię na przykładzie rzeczywistych potrzeb biznesowych oraz cech architektury, a także funkcjonalnych i niefunkcjonalnych wymagań, jakie ta architektura musi spełnić. Duży nacisk położę na samą migrację i modernizację aplikacji, wykraczającą daleko poza tradycyjne podejścia typu „lift and shift”, a nawet poza standardowe wzorce takie jak, m.in. migracja np. do chmury PaaS.
Pomimo mocnego skupienia na wydajności technicznej, artykuł uwzględnia również czynniki biznesowe, które zostaną omówione szczegółowo w kolejnym materiale z serii. Aby urozmaicić tekst o migracji i modernizacji aplikacji, posłużę się realnym przykładem: aplikacją Airline Rewards.
Rozważania architektoniczne dotyczące modernizacji aplikacji Airline Rewards
Aplikacja, której używam jako przykładu, to aplikacja linii lotniczych, która pozwala na przydzielanie nagród i zwiększanie przywiązania użytkowników do marki. Jej obecna forma składa się z kilku prostych stron internetowych, które pozwalają zalogowanej osobie zobaczyć swoje przeszłe loty, przemierzone w ten sposób odległości (mile), segmenty, obecny status nagród oraz zarządzać prostymi informacjami o profilu, takimi jak nazwisko i adres. Pracownicy linii lotniczych mogą zarządzać kontami pracowników i klientów, edytować historię mil i segmentów, a także prowadzić sklep z nagrodami. Aplikacja jest dostępna tylko poprzez stronę internetową; nie posiada wersji mobilnej.
Linia lotnicza ma wielką wizję masowego rozszerzenia tego projektu, m.in. o:
- możliwość pokazania nadchodzących lotów,
- opcje anulowania i rezerwowania lotów za pomocą nagród,
- integrację z partnerskimi liniami lotniczymi,
- aplikację mobilną wraz z powiadomieniami SMS,
- zarządzanie informacjami o płatnościach,
- statystyki wokół historii podróży,
- grywalizację związaną z historią lotów i aktualizacjami.
Możemy przyjąć pewne założenia dotyczące naszej wizji. Bierzemy monolityczną aplikację i migrujemy ją do mikroserwisowej platformy bezserwerowej, ze starszej monolitycznej, aby rozwiązać szereg rozważań opisanych poniżej. Chociaż nie ma nic z natury złego w monolitycznej aplikacji w jej obecnym kształcie, istnieją wymagania lepiej spełnione przez nową architekturę. Ponieważ aplikacja ma być wyposażona w znaczną liczbę dodatków do funkcji, obecny czas jest idealny, aby dokonać tych zmian.
Wyzwania związane z architekturą monolityczną: złożoność i skalowalność procesu migracji do chmury
Istniejąca architektura wykorzystuje nowoczesne podejście monolityczne, framework MVC (model view-control) oraz prostą bazę danych. Chociaż nie jest to złe podejście, wymaga ono, aby wszelkie zmiany w usługach były dobrze rozumiane przez większość zespołu programistów. W miarę rozwoju kolejnych usług migracyjnych i wdrażania nowych funkcji, zespół będzie się powiększał, aby pomóc w utrzymaniu rosnącej ilości usprawnień. Liczba funkcji i wewnętrzna złożoność każdej z nich rośnie i będzie rosła poza możliwości zrozumienia przez jedną osobę, uzasadniając tym samym potrzebę odmiennego, tj. niemonolitycznego modelu.
Poniższy diagram przedstawia istniejącą architekturę wysokopoziomową. Zauważ, że istnieje znacznie większa złożoność w bazie kodu, jeśli poszczególne ścieżki URL i punkty wejścia API miały być odwzorowane wraz z różnymi interakcjami i zależnościami struktury (framework’a). Dla zwięzłości wyłączymy je z istniejącej aplikacji – pokażemy je w późniejszych artykułach z serii.
Architektura jest prosta: dwie główne maszyny wirtualne działające redundantnie, za load balancer’em. Nie mają skonfigurowanego współdzielenia sesji, więc aktywne sesje traciłyby dane, a w środowisku chmurowym mogłyby wystąpić niezrównoważenie pomiędzy maszynami.
Rysunek 1: HLD (High-Level Architecture Diagram) istniejącej aplikacji
Uchwycenie wymagań technicznych i biznesowych dla złożonego systemu zarządzania użytkownikami
Dzięki wcześniejszym działaniom warsztatowym, możemy skategoryzować kilka wymagań. Niektóre z nich mogą być natury technicznej, inne będą umotywowane biznesowo. Razem zdefiniują przyszłe rozwiązanie i proponowaną architekturę.
Biorąc pod uwagę charakter aplikacji, będziemy mieli do czynienia z wieloma użytkownikami a co się z tym wiąże, także wieloma rolami, które muszą zostać zdefiniowane wraz z odpowiednimi uprawnieniami i widokami aplikacji. Chociaż niektóre z nich (ról) można pogrupować pod względem ogólnych uprawnień: np. grupa klientów/rodziny, agenci, pracownicy świadczeń i administratorzy; to i tak każda będzie potrzebowała własnej złożonej obsługi uprawnień i widoków. To wymaga dobrze przemyślanego systemu zarządzania użytkownikami, zdolnego do definiowania ról i polityk dostępu.
Tabela 1: Persony i kohorty użytkowników
| Persona | | Definicja |
| Klienci linii lotniczych | | Klienci końcowi linii lotniczych; osoby, które kupują bilety i uczestniczą w programie lojalnościowym. |
| Grupy rodzinne | | Połączone grupy klientów w ramach tego samego gospodarstwa domowego, którzy gromadzą i dzielą się korzyściami jako grupa. |
| Agenci korporacyjni | | Pracownicy korporacyjni odpowiedzialni za część lub wszystkie rezerwacje klientów indywidualnych |
| Biura podróży | | Pojedynczy użytkownik lub grupa użytkowników, którzy mogą rezerwować, a następnie dokonywać zmian tych rezerwacji dla jednego lub wielu klientów jednocześnie. |
| Agenci linii lotniczych | | Agenci wewnętrzni, którzy mogą dokonywać zmian w każdej rezerwacji dla każdego klienta. |
| Pracownicy świadczeń | | Pracownicy wewnętrzni, którzy mogą zmieniać przyznane nagrody, usuwać i modyfikować historię konta, ale nie mogą modyfikować ani tworzyć rezerwacji. |
| Administratorzy aplikacji | | Pracownicy wewnętrzni mający kontrolę nad modyfikacją wszystkich kont uwierzytelniających: wewnętrznych i zewnętrznych, w tym innych administratorów. |
Wymagania techniczne i cechy charakterystyczne dla platformy linii lotniczych
Wymagania dotyczące platformy dla nowej aplikacji obejmują kilka kluczowych cech, które są niezbędne dla nowoczesnej platformy chmurowej i jej właściwego funkcjonowania:
- szybkie prototypowanie i wdrażanie nowych funkcjonalności,
- możliwość powielania interakcji pomiędzy aplikacjami webowymi i mobilnymi bez konieczności ich całkowitego przepisywania,
- wszystkie strony muszą być obsługiwane poprzez API i zdolne do ładowania danych z wielu wewnętrznych i zewnętrznych źródeł,
- aktualizacja jednej platformy API (np. rezerwacje lotów) powinna być możliwa bez wpływu na zespoły pracujące w innych obszarach (np. świadczenia),
- platforma musi wykorzystywać istniejące, gotowe do użycia rozwiązania dla wspólnych cech (np. do zarządzania użytkownikami, renderowania stron, API), tam gdzie to właściwe, w celu zmniejszenia obciążenia programistów i uproszczenia utrzymania,
- nie musi istnieć wspólne repozytorium danych; komunikacja między funkcjami (np. rezerwacje a nagrody) będzie odbywać się za pośrednictwem API, a nie na zasadzie bezpośredniego dostępu,
- platforma musi mieć możliwość łatwego wysyłania powiadomień SMS i email, a także powiadomień push z aplikacji (np. zmiana terminu lotu),
- platforma musi być zaprojektowana z myślą o możliwości przechowywania i wykorzystywania informacji o kartach kredytowych i związanym z tym wpływem na zgodność z PCI,
- platforma musi wspierać analitykę biznesową i generować wizualizacje statystyczne,
- platforma musi posiadać mechanizmy zarządzania cyklem życia danych, ponieważ muszą być one dostępne dla różnych osób i celów regulacyjnych, w różnych odstępach czasu, a ostatecznie zostać zarchiwizowane.
- platforma musi dostarczać usprawnienia i funkcjonalności dla pasażerów:
- możliwość zapisania się do platformy nagród i rezerwacji,
- wyszukiwanie, rezerwowanie, modyfikowanie, anulowanie i wyświetlanie nadchodzących lotów, w tym zmianę dat, klasy taryfowej i trasy,
- wyświetlanie nagród, wykorzystywanie lub wymianę nagrody, przeliczanie nagrody od partnerskich linii lotniczych, otrzymywanie nagrody od partnerskich linii lotniczych i rozpoznawanie rezerwacji w partnerskich liniach lotniczych,
- integrację z partnerskimi liniami lotniczymi w celu wysyłania informacji o rezerwacjach i wykorzystaniu nagród, w tym udostępnianie zdobytych punktów/segmentów (nagradzanych także przez partnerskie linie lotnicze),
- śledzenie bagażu, najlepiej poprzez kody lotniskowe, odwzorowanie tras i opcjonalne tagi geolokalizacyjne z chipami obsługującymi 4g/5g,
- umożliwienie użytkownikom zarządzania informacjami o profilu, powiązanych kontach/planach rodzinnych, informacjami rozliczeniowymi, zniżkami i innymi istotnymi danymi,
- umożliwienie platformie oferowania motywacyjnych gier podróżnych, w tym gier typu „geocache” w obrębie lotnisk i wokół nich do wybranych miejsc docelowych, gier typu „złap flagę” z kodem QR, odznaczeń liderów i nagród,
- umożliwienie pasażerom linii lotniczych sprawdzenie postępów w zakresie statusu nagrody, a także statystyki punktów.
- platforma musi wspierać różne funkcjonalności agentów i pracowników świadczeń, w tym:
- wyszukiwanie, zarządzanie i modyfikowanie rezerwacji, a także wszystkich informacji o trasie, miejscach siedzących, kabinie i innych informacji dotyczących danej rezerwacji/biletu/PNR,
- łączenie profili, rezerwacji, PNR i innych wymagań i zgłoszeń od pasażerów,
- resetowanie, odbieranie, tworzenie i ręczne rejestrowanie pasażerów,
- podejmowanie działań na rzecz użytkownika w stosunku do konkretnej rezerwacji,
- udzielanie zniżek, zwrotów kosztów i wymianę poniesionych kosztów z anulowanego, na inny bilet,
- zarządzanie nagrodami i ich dostępnością.
- Administratorzy muszą mieć możliwość zarządzania użytkownikami i przypisywania im ról, a także zarządzania agentami rejestracji i pracownikami wszystkich typów.
Zasadnicze wymagania dotyczące platformy:
- łatwość obsługi przez użytkownika końcowego,
- wersja mobilna,
- możliwość zezwolenia zespołom programistów na rozszerzenie funkcjonalności poszczególnych elementów witryny,
- uproszczenia funkcjonalności od strony technicznej, dla odciążenia zespołu programistów.
- integracja API stron trzecich.
Filozofia wyboru cech dla migracji do chmury i modernizacji aplikacji
Ważne jest, aby zrozumieć i zaakceptować fakt, że nie można rozwiązać wszystkich potencjalnych problemów za pomocą pojedynczego narzędzia czy działania, a przynajmniej nie powinno to być głównym założeniem. Rozwiązania muszą spełnić najpierw podstawowe kryteria, które będą podlegać dalszym ustaleniom doprowadzając do ogólnego zarysu projektu, na podstawie którego następnie dopracowuje się poszczególne elementy. Istnieje nieskończona ilość sposobów na to, by określić charakterystykę i wyznaczyć logikę architektury rozwiązania. W tym artykule, skupiliśmy się na wykorzystaniu podejścia Marka Richard’a do cech architektury, dostosowując je do własnych, specyficznych przypadków użycia.
Intencją tego ćwiczenia jest wybranie najbardziej krytycznych biznesowo architektur, które zostały wcześniej zidentyfikowane, a następnie rozpatrzenie ich najlepiej jak potrafimy, biorąc pod uwagę kompromisy pomiędzy aspektami technicznymi w naszym ogólnym projekcie platformy.
Wybrane cechy architektoniczne
a. Ewolucyjność (rozwojowość)
Ze względu na stale zmieniający się charakter działań i oczekiwań klientów, wraz z niepewnością dotyczącą podróży, ograniczeń w podróżowaniu oraz dostarczaniu bodźców motywacyjnych użytkownikom, (nie wspominając o ekosystemie partnerstw, z którymi ta aplikacja musi współdziałać), ewolucyjność będzie podstawowym czynnikiem branym pod uwagę w przypadku tej platformy.
b. „Obsługiwalność”
Platforma musi być dostosowana do szerokiego grona potencjalnych odbiorców, zarówno z punktu widzenia technologii (np. starsze urządzenia, nowoczesne telefony i archaiczne API), jak i języków, walut oraz użytkowników niepełnosprawnych. API musi wspierać każdy interfejs na wypadek, gdyby pojawiły się nowe modele konsumpcji. Idealnie rozwiązanie to takie, w którym każda warstwa prezentacji jest niezależna, aby umożliwić łatwiejsze przejście istniejących aplikacji na każdą technologię wyświetlania, która będzie potrzebna. Produkt rozszerza zakres profili, od skrajnie zaawansowanych do bardzo ograniczonych technologicznie, dlatego musi być prosty w obsłudze, a jednocześnie zapewniać zaawansowane funkcje dla dojrzałych technologicznie użytkowników i osób często podróżujących.
c. Bezpieczeństwo danych
System obsługuje i przetwarza znaczną ilość PII (informacji umożliwiających identyfikację osoby) klientów linii lotniczych. Są to m.in. informacje o rezerwacjach, numery KTN (numery podróżnych), numery odwołań, numery identyfikacyjne paszportów i informacje o kartach kredytowych: system przetwarza wrażliwe dane, które mogą stać się celem kradzieży finansowych i kradzieży tożsamości. Zagrożenie związane z cyberatakiem jest więc ogromne. Linie lotnicze są narażone na takie działania przestępcze jak m.in. podszywanie się pod pracowników, działanie tzw. złych aktorów a także proste uszkodzenia danych, które mogą mieć bardzo niekorzystny wpływ na życie klientów. Zapewnienie bezpieczeństwa i integralności centrum danych będzie nadrzędną cechą, której nie można negocjować.
Migracja do chmury i modernizacja aplikacji: drugorzędne względy
Chociaż nie są to główne założenia, musimy wziąć pod uwagę, że istnieją minimalne progi dla niektórych interakcji. W związku z tym udokumentowaliśmy przypadki użycia, które nie są głównymi decyzjami motywacyjnymi, ale tam, gdzie to możliwe i właściwe, powinny być uwzględnione.
a. Responsywność
Ponieważ aplikacja jest skierowana do użytkownika, musi reagować na dane wprowadzane przez niego. Mowa tutaj o szybkiej rakcji w przypadku długotrwałych interakcji (np. wyszukiwanie lotów w celu wyszukania skomplikowanych tras). Nie oczekujemy, że żądania będą w 100% realizowane w ramach progu Doherty’ego wynoszącego 400ms, ale wszystkie intearkacje muszą pokazywac jakieś działania mające miejsce znacznie poniżej tego progu.
b. Opłacalność
Zarówno koszty bezpośrednie, jak i pośrednie związane z prędkością są czynnikami motywującymi. Produkt ma budżet i ograniczenia czasowe, ale są one tylko ograniczeniami, a nie główną motywacją. Rozwiązanie, które kosztuje więcej lub jego stworzenie zajmuje więcej czasu, za to da lepsze doświadczenia użytkownikom lub pozwoli na szybsze tempo rozwoju produktu w przyszłości, jest akceptowalnym kompromisem.
Proponowana architektura rozwiązania: poziom podstawowy
Rozwiązanie przedstawione poniżej (rys. 2) posiada krótki opis (więcej szczegółów przedstawię w kolejnych artykułach) i pokazuje różne kompromisy podjęte w trakcie omawiania projektu, a także pełne opisy komponentów. Budujemy na architekturze bazowej, z biegiem czasu i wraz z pojawieniem się nowych potrzeb, dodając komponenty i szczegóły aby uzyskać w pełni rozwinięte rozwiązanie.
W przypadku architektury bazowej, podczas procesu projektowania skupiliśmy się przede wszystkim na znalezieniu odpowiedniej platformy, która byłaby oparta na mikroserwisach bezserwerowych (Serverless), ponieważ pozwoliłoby to dodać nowoczesne komponenty, w tym SaaS (oprogramowanie jako usługa), PaaS (platforma jako usługa) i DBaaS (baza danych jako usługa), według naszego uznania. Ta architektura może być opcjonalnie rozszerzona o obsługę dowolnej liczby różnych komponentów oprogramowania, od tradycyjnych VM (maszyn wirtualnych) i kontenerów API, przez tzw. „3cią stroną”, i inne usługi Serverless, od wybranego przez nas dostawcy chmury – w tym przypadku AWS. Platforma Serverless Microservices jest ściśle mówiąc zapożyczeniem z wielu stylów architektury, ale dobrze pasuje do tego konkretnego zestawu kryteriów problemu.
Proponowana architektura rozwiązania: wstępny wybór komponentów
Początkowy wybór komponentów pozwala na szybkie stworzenie prototypu i rozwój, dzięki wysoce „wtyczkowej” aplikacji (takiej, która może zostać zintegrowana z wieloma różnymi, innymi aplikacjami) pozwalającej różnym zespołom na niezależną pracę nad rozwojem funkcjonalności, za które odpowiadają.
Wykorzystanie wzmocnienia dzięki Cognito pozwala na:
- obsługę znacznej liczby ogólnych zadań, takich jak obsługa użytkowników i sesji,
- uwierzytelnianie, mapowanie ról i wiele innych czynności, które są zawarte w zgrabnym pakiecie do szybkiego wdrożenia,
- szybsze cykle rozwoju, przy zmniejszeniu tzw. kosztów zasobów ludzkich.
Co więcej, platforma jest domyślnie przyjazna zarówno dla stron internetowych, jak i urządzeń mobilnych. Możliwość szybkiego tworzenia wielu widoków i interfejsów z treścią rozwiązuje wiele problemów związanych z obsługą, w tym interfejsów ADL (activities of daily living) dla osób niepełnosprawnych, (m.in. stron, które są przyjazne dla czytników ekranu i innych produktów wspomagających). Wreszcie, platforma jest bardzo przyjazna dla użytkownika, obsługując wiele ścieżek powiadomień, (w tym SMS w wielu krajach), i pozwala użytkownikom uwierzytelniać się za pomocą preferowanego dostawcy tożsamości, podczas gdy biura podróży i pracownicy wewnętrzni mogą korzystać z SAML i OpenID.
Proponowana architektura rozwiązania: bezpieczeństwo komponentów oraz przyszłe kierunki działania
Wszystkie wybrane komponenty:
- są wysoce odporne na cyberataki i obsługują różne sposoby weryfikacji integralności danych i dostępu do nich,
- rejestrują i audytują dostęp, zmianę kodu, danych , w tym dostęp do API,
- są domyślnie bezpieczne, bazując na istniejącym zaufanym ekosystemie wspieranym przez AWS i sprawdzonym przez tysiące instalacji produkcyjnych. Koszt architektury może być stosunkowo niski, a świetnie nadaje się do szybkiego reagowania w razie problemów.
Szerszy opis poszczególnych usług, w tym ich wady i zalety z uwzględnieniem kwestii rozwoju oraz eksploatacji aplikacji, zostaną przedstawione w kolejnym artykule (plan całej serii umieszczamy na końcu tekstu). Przedstawione w niniejszym artykule komponenty nie są kompletną architekturą, stanowią jednak solidną podstawę, z której można budować jej zarys.
Rysunek 2: HLD (High-Level Architecture Diagram)
Uwaga: Szczegółowe rozbicie składników oraz odwzorowanie stylów z HLD zostanie przedstawione w kolejnym artykule.
Podziękowania dla:
Co jeszcze przed nami? Migracja aplikacji i jej modernizacja – seria artykułów
W trakcie naszej „podróży” w kierunku migracji do chmury i modernizacji aplikacji wydarzyć się może wiele, od dyskusji nad koncepcją, do uzyskania pełnego planu aplikacji. W artykułach przedstawiamy dokładną analizę, chociaż w realnych sytuacjach, nie każda modernizacja aplikacje wymaga aż tak szeroko zakrojonych działań. Niemniej, podczas każdej, wykorzystane będą przynajmniej części omówionych przez nas metod. Dlatego w serii artykułów krok po kroku poprowadzimy czytelników przez proces aby pomóc im wybrać najważniejsze zagadnienia i zdecydować, jakie działania zastosować, a które odrzucić. Umieszczenie wszystkich kroków w jednym artykule stworzyłoby zapewne krótką książkę, a i tak nadal nie wyczerpywałoby w pełni zagadnienia.
- Etap Discovery & zbieranie wymagań biznesowych (artykuł wkrótce)
- Mapowanie uchwyconych wymagań i istniejącego rozwiązania do wysokopoziomowej architektury (omówione w tym artykule)
- Projektowanie procesów, sekwencji, UX Workflows & UI Wireframes
- Zaprojektowanie spójnego procesu wdrażania
- Tworzenie diagramów C4 (System Context, Container diagrams)
- Dołączenie raportowania i Business Intelligence (BI)
- Określenie ryzyk i migracji (biznesowych i technicznych)
- Tworzenie Architectural Decision Records (ADR), omawianie kompromisów i zbieranie informacji zwrotnych dotyczących decyzji
- Podział kosztów posiadania (wdrożenie, bieżące koszty operacyjne, bieżące koszty infrastruktury i chmury, bezpieczeństwa i ryzyka)
- Zdefiniowanie wspólnych definicji projektowych i glosariusza
- Stworzenie backlogu projektu (kamienie milowe, epopeje, przechwytywanie informacji niefunkcjonalnych)
- Rozważania dotyczące zarządzania operacyjnego i bieżącego
- Kompletny pseudo projekt gotowy do pracy (repozytorium GitHub)