Zadań ciąg dalszy — tym razem początkujący zmierzą się z diagramem aktywności. Dla praktyków coś nieco innego — słów kilka o architekturze i budowaniu systemów. Gotowa?
Wyzwanie dla początkujących
Przed przystąpieniem do zadania, zastanów się nad rezultatem Twojej wczorajszej pracy: Czego dowiedziałeś się o swoich umiejętnościach? Czego się nauczyłeś? Co zrobisz z tą wiedzą?
Dość częstym problemem początkujących programistów jest ‘jak to podzielić’/‘gdzie to zaimplementować’. Już średniego rozmiaru aplikacja będzie miała kilkanaście modułów, kilkadziesiąt różnych klas, kilka warstw — odnalezienie się w tym wszystkim to niekoniecznie łatwe zadanie. Czasami może pomóc dokumentacja, czasem pomoże nam ktoś z zespołu, ale sama też możesz do tego dojść w prosty sposób!
Jednym ze sposobów jest diagram aktywności — technika obrazowania nie tyle samego systemu czy jego technicznych zawiłości, ile właśnie procesów i danych, które w ramach tych procesów są przetwarzane. Na naszym blogu znajdziesz też wpis na ten temat :)
Twoim zadaniem będzie stworzyć diagram aktywności dla jakiejś czynności, którą codziennie wykonujesz. Może to być np. proces zakupów, przygotowania posiłku czy np Twoja wieczorna rutyna. W tym wypadku ‘danymi’ mogą być też przedmioty, których używasz w tym procesie, a ‘partycjami’ — miejsca lub osoby, które w nim także uczestniczą.
Po stworzeniu diagramu, zastanów się, czy mogłabyś zastosować tą technikę do jakiegoś problemu w pracy, który miałaś w ostatnim czasie. Jeśli tak, jak wyglądałyby podstawowe partycje i akcje? Czy potrafisz przedstawić swoje rozwiązanie za pomocą diagramu aktywności?
Jeśli chodzi o narzędzia, najprostszym jest po prostu kartka i długopis ;) Możesz też skorzystać z narzędzi takich jak gliffy.com (bezpłatne konto pozwala na stworzenie do 5 publicznych diagramów) albo jednego z wymienionych na Wikipedii.
Nie zapomnij podzielić się z nami swoim pomysłem w komentarzu pod eventem na FB!
Nasza odpowiedź
Niby prasować każdy umie, jednak ja kilka razy musiałam uzupełniać swój diagram aktywności ;)
- użycie tej metody zmusiło mnie do refleksji w jakiej kolejności oglądam pranie, założyłam, że najpierw sprawdzam, czy jest czyste, potem czy suche, a dopiero potem, czy prasuje daną rzecz. Tak to się również dzieje w rzeczywistości, poza niespranymi plamami, które odkrywamy już na desce ;) Chociaż może macie zupełnie inne patenty na ten temat ;)
- w przypadku temperatury poszłam na porządkową łatwiznę — ostatnio znajoma podesłała mi life hacka by na samym początku prasowania układać ubrania od najniższej temp prasowania do najwyższej, jednak w moim diagramie po prostu dla każdego ubrania dobieramy temperaturę. Nie jest to optymalny sposób, bo studzenie żelazka czy jego nagrzewanie zajmują czas (i pieniądze). I myślę sobie, że w przypadku aplikacji czasem też może nam się pojawić takie dostosowywanie do każdego, a można by było je uprosić sortując odpowiednio przyjmowane obiekty.
Wyzwanie dla praktyków
Przed przystąpieniem do zadania, zastanów się nad rezultatem wczorajszej pracy: Czego dowiedziałeś się o swoich umiejętnościach? Czego się nauczyłeś? Co zrobisz z tą wiedzą?
Architektura aplikacji jest zagadnieniem stosunkowo prostym i bardzo skomplikowanym zarazem. Prostym, ponieważ wiele już zostało w tym temacie powiedziane — istnieją wzorce (np. Enterprise Integration Patterns), ich implementacje (np. Apache Camel), gotowe klocki do budowy rozwiązania (np. Amazon AWS, Microsoft Azure), a także wzorcowe rozwiązania (jak np. AWS Blueprints). Jednocześnie jest to zagadnienie bardzo skomplikowane, ponieważ często wymagania są minimalnie inne niż te ‘wzorcowe’, opracowanie architektury aplikacja wymaga znajomości szczegółów jak poszczególne elementy ze sobą współpracują, jakie są konsekwencje pewnych decyzji oraz jak zmiana określonych parametrów wpływa na pozostałe.
W zdecydowanej większości aplikacji można sobie pozwolić na pewne błędy — większość aplikacji, z którymi pracujemy na codzień będzie działała tylko na kilku serwerach, a ich kilkuminutowa awaria nie spowoduje większych problemów. Zapewne też pracowałaś z takim projektem. Dzisiejsze zadanie polega na przeprojektowaniu systemu, który projektowałaś w przyszłości. Zaczynając od wymagań niefunkcjonalnych oraz głównych założeń, stwórz od nowa ‘idealną’ architekturę takiej aplikacji.
Oczywiście postaraj się zmieścić w godzinie czasu — mówimy więc tutaj o bardzo wysokopoziomowym spojrzeniu. Postaraj się jednak odpowiedzieć na kilka pytań:
- co się stanie, kiedy jeden z serwerów przestanie działać? Co się stanie jeśli cała serwerownia przestanie działać?
- które cechy były w Twoim systemie najważniejsze i dlaczego? jakie kompromisy musiałaś w związku z tym podjąć?
- jakie są limity Twojego systemu? który element będzie najbardziej ograniczał jego możliwości?
Jeśli potrzebujesz inspiracji albo chciałabyś zerknąć, jak zaleca się budować podobne systemy możesz skorzystać z zasobów AWS (na dole jest sekcja ‘AWS reference architectures’) lub Azure. Możesz też skorzystać z opisów Enterprise Integration Patterns.
Jeśli możesz — podziel się swoimi przemyśleniami w komentarzu pod wydarzeniem na FB :)
Nasza odpowiedź
Projekt, który wybrałem to system do automatycznego mailingu — taki odpowiednik MailChimpa i GetResponse z czasów, kiedy programy te nie były zbyt popularne ;) Jeden z ważniejszych czynników w tego rodzaju aplikacjach to osobne adresy IP dla różnych klientów — w sytuacji kiedy jeden z nich zostanie uznany za spam, nie może to mieć wpływu na pozostałych klientów. System ten był skierowany do przedsiębiorców prowadzących sprzedaż online — z tego powodu koszty utrzymania nie były najistotniejsze (wtedy sprowadzało się to do tego, że każdy klient instalował oprogramowanie u siebie, na własnym serwerze VPS). To jednak dotyczy wyłącznie części odpowiedzialnej za ‚wysyłanie’ maili, jeśli chodzi o samą część związaną z konfiguracją fakt instalacji na serwerach klientów przysparzał więcej problemów niż korzyści. Aplikacja, którą wtedy zaprojektowałem i zaimplementowałem była monolityczna, a poszczególne jej instancje nie komunikowały się ze sobą w żaden sposób.
Podsumowując wymagania:
- sama wysyłka wiadomości powinna odbywać się w miarę możliwości z osobnych adresów IP dla każdego z klientów (można powiedzieć, że to taka wariacja w temacie Cell Architecture)
- część konfiguracyjna oraz interfejs użytkownika może być współdzielony pomiędzy klientami
- obciążenie systemu jest skokowe (w momencie wysyłek), ruch związany z interfejsem jest standardowy, z silnym trendem spadkowym podczas weekendów
- interfejs musi być dostępny pod wieloma domenami (z uwagi na scoring antyspamowy, linki w treści maili powinny kierować do tej samej domeny, z której został wysłany mail)
Proponowana architektura:
Diagram przygotowany został w oparciu o publicznie dostępne usługi AWS.
Wszyscy klienci są obsługiwani przez wspólną flotę serwerów — wspólna jest też baza danych przechowująca konfigurację. Aplikacja jest oparta o serwisy RESTowe, wystarczy nam więc warstwa aplikacji oraz sieć CDN do serwowania ruchu statycznego. Punkt wejściowy aplikacji to Route53 — usługa DNS, która pozwoli nam odpowiednio serwować zarówno treści statyczne jak i serwisy RESTowe dla wielu domen za pomocą tych samych serwerów. Dane statyczne obsługiwane są przez CloudFormation oraz usługę S3, zapytania dynamiczne (poprzez Load Balancer) serwowane są za pomocą usługi EC2 — standardowej chmury obliczeniowej.
Poszczególne serwery mają wspólną bazę danych, dla bezpieczeństwa posiadającą repliki w różnych strefach. W tym wypadku baza danych jest relacyjna, co może być ograniczeniem jeśli chodzi o skalowalność aplikacji.
Serwery aplikacji ‚zlecają’ wysyłkę wiadomości email do osobnej floty — w tym wypadku w zależności od preferencji klienta może to być usługa SES, mogą to być osobne serwery (dla specyficznych zastosowań i konfiguracji), a mogą to być także serwery hostowane u klienta (jesli jest potrzeba integracji z wewnętrznymi systemami jak np. AD — wtedy komunikacja nawiązywana jest przez VPN).
Potencjalne zmiany / usprawnienia:
- system nie jest wrażliwy na czas odpowiedzi, o ile jest on poniżej sekundy; można rozważyć rezygnację ze standardowych serwerów EC2 i zastąpić je np. AWS Lambda — obliczeniami na żądanie. Mogłoby to jednak negatywnie wpłynąć na szybkość wdrażania zmian i nowych funkcji, a ilość interakcji z UI jest na tyle mała, że nie generowało by to znaczących oszczędności.
- aby zwiększyć możliwości aplikacji, można zastąpić relacyjną bazę danych połączeniem np. DynamoDB (do przechowywania danych) z usługą ElasticSearch (pozwalającą wyszukiwać informacje we względnie dowolny sposób) — z drugiej strony ilość przetwarzanych informacji jest względnie niewielka, i relacyjna baza danych powinna być wystarczająca nawet przy liczbie klientów liczonych w dziesiątkach tysięcy
Oczywiście obecnie istnieje wiele gotowych rozwiązań, które można dopasowywać do własnych potrzeb — produkt tego rodzaju raczej nie miałby zastosowania. Mimo wszystko było to przyjemne doświadczenie — często w codziennej pracy nie można sobie pozwolić na ‚idealny’ projekt od strony technicznej, bo jest wiele innych czynników, które należy uwzględnić. Było to także ciekawe pod tym kątem, że odświeżyłem sobie usługi oferowane przez różnych dostawców chmur :)
Cały system jest też w prosty sposób przenaszalny, jeśli klient życzy sobie mieć całkowicie prywatną instalację.
Pamiętaj, że nowe zadania będą się pojawiać codziennie o godzinie 11. Rozwiązania będziemy umieszczać pod zadaniami kolejnego dnia o godzinie 18. Nie zapomnij podzielić się swoimi odpowiedziami i przemyśleniami na wydarzeniu na facebooku, a jak masz ochotę to też w komentarzu ;)!
Linki do wszystkich zadań znajdziesz w innym wpisie na naszym blogu. Powodzenia!