Komunikacja między mikroserwisami

Jednym z pierwszych wyzwań stojących przed mikroserwisami jest wybór sposobu komunikacji.

photo-1475691058852-37b5d9b6a878

Wybór rodzaju interakcji

Wybierając odpowiedni w danym przypadku styl interakcji musimy zbadać jakiego rodzaju komunikacją mamy do czynienia. Mamy tutaj do wyboru:

  1. Jeden do jednego – inicjator wykonuje żądanie, które jest przetwarzane przez dokładnie jeden serwis odbierający żądanie
  2. Jeden do wielu – w tym modelu wiadomość może być przetwarzana przez wiele serwisów odbierających (w szczególnym wypadku może być to jeden lub zero serwisów). Zazwyczaj dla serwisu inicjującego konwersacje, będzie transparentne to ile serwisów przetwarza to żądanie

Styl interakcji

Wybór stylu interakcji sprowadza się do pytania czy komunikacja ma charakter synchroniczny czy asynchroniczny:

  1. Komunikacja synchroniczna – inicjator czeka na odpowiedź
  2. Komunikacja asynchroniczna – inicjator nie czeka na odpowiedź

tony-stoddard-DgZxBnZeQo8-unsplashsource:Photo by Tony Stoddard on Unsplash

Najpopularniejszymi wzorcami interakcji są:

  1. Odpal i zapomnij (ang. fire-and-forget) – inicjator konwersacji wysyła wiadomość, która dociera do odbiorcy. I to w zasadzie tyle. Ciężko sobie wyobraźić prostszy schemat konwersacji.2017-07-23 18_22_11-BlogGD - microservices pt3.png - Paint
  2. Zapytanie/odpowiedź – najczęściej stosowana metoda interakcji. Strona inicjująca odpytuje drugą i czeka na odpowiedź, która powinna pojawić się w określonym czasie.2017-07-23 18_24_32-BlogGD - microservices pt3.png - Paint
  3. Zapytanie/asynchroniczna odpowiedź – polega na wysłaniu zapytania przez klienta do serwisu, który odpowiada asynchronicznie. Jakie ma to implikacje? Otóż klient może w sposób nieblokujący czekać na odpowiedź. Nic nie stoi na przeszkodzie by w tym czasie robić inne obliczenia. Do klienta należy obsługa całkiem prawdopodobnej sytuacji, iż takiej odpowiedź nie dojdzie.2017-07-23 18_24_43-BlogGD - microservices pt3.png - Paint
  4. Publikacja/subskrypcja – przesyłanie wiadomości polega tutaj na udostępnianiu informacji przez publikatorów, a ich odbiorcami są wszystkie jednostki w systemie, które są zainteresowane danym komunikatem.2017-07-23 18_24_55-BlogGD - microservices pt3.png - Paint

Technikalia

Posiadając do wyboru kilka możliwych wzorców interakcji musimy zdecydować się jeszcze na techniczne szczegóły co do sposobu w jaki taka interakcja zostanie zrealizowana.

By zapewnić jak najlepszą niezawodność systemu przy wysokiej wydajności i skalowalności, najczęściej najlepszym wyborem będzie kombinacja technologii komunikacji. W różnych miejscach systemu możemy zastosować różne sposoby komunikacji:

  1. HTTP/REST API
  2. Wiadomości (messaging)
  3. Inny, specyficzny dla domeny protokół komunikacji

W zależności od tego który ze sposobów komunikacji wybierzemy musimy liczyć się z konsekwencjami. I tak:

1. HTTP/REST API

pavan-trikutam-71CjSSB83Wo-unsplashSource:Photo by Pavan Trikutam on Unsplash

Szybki, elastyczny sposób na implementację komunikacji pomiędzy serwisami. Dla większości programistów będzie to także po prostu najprostsze w użyciu narzędzie. Często wykorzystywany do wykonywania zapytań (w odróżnieniu do komend). Dużym plusem jest brak narzutu co do konkretnej technologii. Serwisy wykorzystujące komunikację poprzez HTTP/REST API mogą korzystać z szerokiej gamy rozwiązań. Co najważniejsze, nie ma problemu by po obu stronach komunikacji występowały całkowicie różne technologie.

Ta technologia, w najprostszej wersji, charakteryzuje się synchronicznością działania co w zależności od kontekstu będzie zaletą bądź też wadą. Dzięki powszechnej znajomości tego rozwiązania zazwyczaj nie będzie problemu z zastosowaniem tego rozwiązania. Definitywnym minusem tego rozwiązania jest wrażliwość na problemy z dostępem do sieci, w chwili wykonywania zapytania obie strony interakcji muszą działać. Inną wadą jest wymaganie znajomości adresu serwisu przez klienta. Intuicyjnie może to nie wydawać się jak duży problem, aczkolwiek skalowanie systemu wymaga od nas by klient mógł i wiedział jak może połączyć się z wszystkimi instancjami danego serwisu.

2. Wiadomości (messaging)

andrew-buchanan-2EdeFVe8TOE-unsplash

Wymiana informacji pomiędzy serwisami za pomocą wiadomości to świetny sposób na rozluźnienie powiązania pomiędzy nimi. Ta, z natury asynchroniczna, komunikacja polega na tym, że jedna ze stron komunikacji zapisuje wiadomość, natomiast druga ją odczytuje. Dobrze to współgra z wzorcami architektonicznymi takimi jak CQRS i EDD (Event-Driven Development). Decydując się na ten sposób komunikacji, musimy podjąć decyzję jakiej technologii użyjemy. Przykładowymi, popularnymi rozwiązaniami są: Apache Kafka, AWS Kinesis Streams, Azure Service Bus, RabbitMQ, NServiceBus, MassTransit, MSMQ. Wspomniane rozwiązania różnią się znacznie podejściem do architektury systemu, poziomem abstrakcji i sam opis tychże różnic to spory temat. Dodatkowo mamy tutaj spory wachlarz wzorców komunikacji jak np. : publikacja/subskrypcja czy też zapytanie/odpowiedź. Możemy tutaj uzyskać wysoką skalowalność jak i wysoką dostępność systemu za cenę dodatowej złożoności systemu spowodowanej wykorzystaniem infrastruktury umożliwiającej komunikację przez wiadomości.

3. Specyficzny protokół komunikacji taki przesył danych binarnych, JSON czy też XML.

Czasami sytuacja zmusza lub też zachęca nas do użycia jakiegoś innego formatu danych. Często jest to uwarunkowane specyficznymi wymaganiami w konkretnej domenie i umożliwia to np. wydajny streaming multimediów.

Komunikacja między serwisami wymaga od nas znajomości charakteru interakcji co potem wpływa na wybór technologii. Każda z tych decyzji niesie za sobą zalety ale i wady, ale mając ich świadomość jesteśmy w stanie zbudować system, który w wydajny sposób się komunikuje i wykorzystuje infrastrukturę by uzyskać zarówno wysoką dostępność jak i niezawodność.

Bibliografia i inne ciekawe materiały:

Pobij Netflixa

Skoro już cię przekonałem dlaczego warto używać chmury oraz dlaczego to może być AWS następnym logicznym krokiem jest przedstawienie jakiegoś przykładowego rozwiązania bazującego na chmurze AWS. Dziś na warsztat weźmiemy rozwiązanie streamingowe, które pozwoli ci pobić Netflixa 😉

woman lying on bed while eating puff corn

 

Domena

Dla uproszczenia dziedziny problemu, przyjmijmy, że chcielibyśmy mniej więcej odzwierciedlić podstawowe funkcjonalności Netflixa (oczywiście zrobimy to lepiej!), czyli dostarczyć rozwiązanie pozwalające na oglądanie wideo na życzenie oraz platformę, która owe wideo serwuje. 
Użytkownik w dzisiejszych czasach jest bardzo wybredny. Mając do czynienia z rozwiązaniami typu HBO Go czy Netfix musimy dostarczyć serwis, która będzie:

Niezawodny

Powiedzmy sobie szczerze ile razy nie działał ci Netflix z ich winy?

Szybki

Jeżeli użytkownik będzie musiał czekać na buforowanie wideo zbyt długo to pójdzie tam gdzie nie musi czekać. To nic osobistego.

Relatywnie tani

Oczywiście możemy kupić najlepsze dostępne serwery, bazy danych itd, ale kiedy przyjdzie nam obsługiwać ruch tysięcy użytkowników to rachunki szybko poszybują na poziomy takie, że szybko zrezygnujemy z naszych ambitnych planów.

Skalowalny

Użytkownika mało obchodzi to, że akurat dziś ruch na naszych serwerach jest 2-3 czy 10 razy większy niż zwykle. To się zdarza, naszym zadaniem jest na to się przygotować.

Ogólna architektura

Pomijając zbędne szczegóły architektura takiego przekrojowego rozwiązania może wyglądać następująco:

Omówmy sobie po kolei wszystkie komponenty

Warstwa API Gateway

Odpowiada za odbiór żądań ze strony urządzeń. Jak mówi nazwa to interfejs do naszego systemu. Wszelkiego rodzaju przeglądarki, smartfony czy też TV będą komunikować się właśnie przez tą warstwę. Tutaj załatwimy sprawę cache-owania żądań, kontroli dostępu i przekierujemy żądania do warstwy serwerów aplikacyjnych.

Warstwa serwerów aplikacyjnych

Tutaj umieścimy obliczenia i całą logikę odpowiedzialną za obsługę żądań. Główny kod odpowiedzialny za synchroniczne przetwarzanie zapytań tak by dostarczyć użytkownikowi odpowiednie „ekrany” i ich zawartość. Od strony infrastruktury, logika odpalana jest oczywiście na serwerach czy też ich klastrach. Częściowo mogą być to lambdy przy podejściu bardziej serverless. Zwłaszcza na początku gdy dopiero rozpatrujemy różne możliwości jest to kuszące rozwiązanie. Mamy tu także wykorzystanie kolejek zadań, cache, baz danych, oraz oczywiście innych mikroserwisów czy to naszych, czy też zewnętrznych rozwiązań – SAAS.

Warstwa zadań asynchronicznych.

Wszystkie zapytania, które nie należą do naszej aplikacji bezpośrednio, ale też muszą się zadziać. Jeżeli chcesz zrobić system chociaż w niewielkim stopniu podobny do Netflixa, czy też go pobić, trzeba sobie uświadomić sobie ogrom pracy jaka jest wykonywana „pod spodem”, czyli po prostu na backendzie.

Co musimy przygotować dla użytkowników?

  • Wideo w odpowiednim formacie. Każde urządzenia to inne wymagania odnośnie formatu czy też rozmiaru. Nie mówiąc o tym, że musimy serwować różne pliki w zależności od szybkości łącza użytkownika.
  • Rekomendacje. Kiedyś to może byłby fajny dodatek, teraz to wymóg by prezentować rekomendacje dla użytkowników, jeżeli trafimy w gusta, +5 punktów dla nas!
  • Newslettery. Byle nie za dużo spamu.
  • Bieżąca obsługa. Reset hasła, usunięcie konta itd

Przestrzeń chmurowa (cloud storage) i CDN

Forma przechowywania danych wideo to jedno z bardziej krytycznych zadań. Trzeba pamiętać o tym, że danych tych będzie bardzo dużo (pamiętasz, że mamy wiele kopii tych samych filmów?) Potencjalne koszty będą tutaj silnie skorelowane właśnie z rozmiarem danych. Z drugiej strony nie możemy sobie pozwolić by dostęp do nich był wolny, inaczej użytkownik szybko wybierze konkurencję. Innymi słowy potrzebujemy hybrydy przestrzeni chmurowej i CDNa. Przestrzeń chmurowa to po prostu serwer plików, a CDN, czyli Content Delivery Network lix-a to rozproszona sieć buforująca często używane zasoby poprzez ich kopiowanie na odpowiednie serwery będące blisko użytkownika końcowego. Będąc w Polsce, możemy szybciej streamować film, jeżeli znajduje się od na serwerze we Wrocławiu, niż gdy znajduje się w Los Angeles, prawda?

Uczenie maszynowe

Tutaj umieszczamy cokolwiek, byle by móc powiedzieć, że „robimy machine learning” i ściągnąć zainteresowanie inwestorów i klientów 😛 A tak na prawdę to skoro chcemy serwować naszym użytkownikom wspomniane wcześniej rekomendacje to dobrze jest móc to robić w oparciu nie o sztywne reguły, a właśnie modele wykorzystujące uczenie maszynowe. Dzięki temu będziemy mogli analizować podobieństwo między różnymi użytkownikami oraz podobieństwo miedzy filmami i na tej podstawie decydować czym dana osoba może być zainteresowana. To wszystko powinno przełożyć na trafniejsze rekomendacje i wzrost zainteresowania naszym rozwiązaniem.

Hurtownia danych

Raporty, analiza danych, musisz trzymać rękę na pulsie. Hurtownia to miejsce gdzie dane te są zorganizowane w przystępnej formie.

AWS

Przestwawię teraz przykładową implementację powyższych komponentów w AWSie. Od razu zaznaczam, że pewne kwestie zostały pominięte dla prostoty diagramu, przykładowo logowanie czy monitoring. Jeżeli chodzi o dobór konkretnych rozwiązań to też mamy do wyboru wielorakie rozwiązania na rynku. Nic nie stoi na przeszkodzie by część z nich było poza AWS, jednak formuła tego artykułu jest taka, że tylko do tej chmury zawęzimy nasz wybór. Dobra, koniec gadania:

Wersja w lepszej rozdzielczości: tutaj

Omówię teraz po krótce kluczowe decyzje.

Warstwa API Gateway

Jak wcześnieś zauważyliśmy, chcemy odpowiednio zopytmalizować wrażenia użytkowników różnych platform. Stąd też podejście typu backend for frontend, czyli warstwa API Gateway posiada wyspecjalizowane dedykowane AWS API Gatewaye w zależności od platformy klienckiej.

Warstwa serwerów aplikacyjnych

Sercem rozwiązania są klastry ECS, czyli Elastic Cloud Server. Tak, konteneryzacja zawitała i do nas! Żądania przychodzą od strony load balancer-a. Do tego SQS do kolejkowania zadań. Jako baza danych może posłużyć nam DynamoDB o ile dobrze czujemy się w środowisku baz NoSQL. Zaletą DynamoDB jest łatwa skalowalność, która jest dla nas niemalże przeźroczysta. Alternatywnie możemy posłużyć się RDS Aurorą.

 Warstwa zadań asynchronicznych

Preview(opens in a new tab)

Od strony infrastruktury wygląda to podobnie jak w przypadku warstwy serwerów aplikacyjnych. Różnicą będzie dużo większe wykorzystanie kolejek SQS, potencjalnie także topic-ów SNS to komunikacji zorientowanej na wiadomości, której będzie tutaj dużo.

Jedno z kluczowych zadań do wykonania w tej warstwie to transcoding wideo, który może wyglądać następująco:

Na wejściu mamy nieskompresowany plik wideo, wrzucony być może przez samego autora filmu. Na wyjściu mamy plik dostosowany przez nas process do odpowiedniego urządzenia końcowego.

Przestrzeń chmurowa (cloud storage) i CDN

Troche już w punkcie poprzednim zostało opowiedziane przy okazji omawiania transcodingu. S3+CloudFront załatwiają sprawę. 

Alternatywne rozwiązania – AWS Media Services

Pewną alternatywą dla nas mogą być AWS Media Services

Z naszej perspektywy użyteczne mogło by być zwłaszcza AWS Elemental MediaConvert, które zapewnia właśnie usługę transcodingu. Dużym plusem jest to, że płacimy tutaj za użycie, czyli tak jak w infrastrukturze powyżej, gdzie brudną robotę wykonują za nas EC2-ki. Myślę, że AWS Elemental MediaConvert możemy rozważyć jako element naszego MVP a docelowo możemy kierować się jednak ku ECS/EC2 gdyż pozwoli nam to na większą elastyczność rozwiązania i zoptymalizowanie kosztów. Zasadniczo reguła kciuka mówi nam, że im bardziej wysokopoziomowe rozwiązanie, tak jak w przypadku AWS Elemental MediaConvert, cena rośnie w sposób adekwatny.

Podsumowanie i dalsze kroki

Tak jak pisałem wyżej. Poza zaprezentowanymi rozwiązaniami pozostaje do doprecyzowania zostaje wiele kwestii pobocznych. Przykładowo do logowania możemy użyć serwisu Cloud Watch. To właśnie Cloud Watcha użyjemy także do monitorowania naszych zasobów oraz podnoszenia odpowiednich alarmów gdy przykładowo będziemy mieli do czynienia z jakimś problemem. Nie chcemy przecież by tak błache rzeczy jak np. brak pamięci na serwerze, błęd w logice serwisu czy tego typu sprawy zaprzepaściły nasz cały wysiłek i popsuły wizerunek pogromcy Netflixa.

Do przesyłu danych może przydać się Kinesis streams. Autentykacja użytkowników może przebiegać w Cognito. Potrzebujemy też dobrego cache-a, Amazon ElastiCache, poratuje. A no i nie obędzie się bez kontroli tego co który serwis może robić a czego nie może zrobić. Tu do gry wkracza IAM. Na tym chyba poprzestanę 🙂


Z pewnością tego typu przekrojowa architektura może nieco odstraszać, aczkolwiek pozwala sobie jednak zdać sprawę jak skomplikowane tworzenie systemów może być gdy nie mamy do dyspozycji tych gotowych serwisów i chcielibyśmy implementować skalowalny system przy pomocy softwareu instalowanego na naszych maszynach.

Fzf czyli twój specjalista od rozmytego wyszukiwania

https://github.com/junegunn/fzf


Co to dla nas znaczy i w czym pomaga to narzędzie? Najprościej będzie wytłumaczyć na przykładach. W końcu jeden przykład jest warty więcej niż 1000 słów czy jakoś tak.

Przykłady

Interaktywne wyszukiwanie

Zacznijmy od najważniejszego, wyszukiwanie odbywa się w sposób interaktywny tzn. zmiana naszego zapytania wpływa od razu na wyświetlane wyniki! Sprawia to, że wyszukiwanie jest po prostu super-wydajne!

Otwieranie pliku

Wyobraźmy sobie, że potrzebuję otworzyć jeden z plików źródłowych z poziomu konsoli. (jak on się nazywał…) 

Załatwione. Jeżeli dana fraza nam nie pasuje możemy strzałkami poruszać się w górę i w dół by wybrać to czego szukaliśmy.

Użycie wyniku w pipeline-nie

Przeszukiwanie plików otwiera przed nami morze możliwości. Nic nie stoi na przeszkodzie by wykorzystać rezultat wyszukiwania w fzf i przykładowo otworzyć wyszukany plik w wybranym edytorze.

fzf | ? { edit $_ }

Potrzebujesz przeszukać pojedyncze linie tekstu w ten sam sposób? Przekierowywujemy tekst do fzf i mamy to! 

To tak na prawdę najpopularniejszy przypadek użycia fzf. Zobacz jak wygodne jest teraz przeszukiwanie pliku.

Jeżeli szukasz jakiegoś kawałka kodu i chcesz to zrobić w sposób interaktywny to fzf ułatwi sprawę 

Jeżeli znudzi nam się standardowy wygląd fzf, mamy też całkiem spore możliwości manipulacji np 

fzf --layout reverse --border --color 'fg:#ff0000,fg+:#55aa66,bg:#00ff00,border:#0000ff'

Są jeszcze inne zastosowania, których sam nie wykorzystuję ale myślę, że warto wiedzieć, że są. Może komuś przypadnie do gustu:

  • Przechodzenie po folderach, można wykorzystać fzf do znajdywania interesującego folderu w drzewie.
  • Zabijanie procesów bazując na wyniku wyszukiwania z fzf do którego przekazujemy listę procesów.
  • Przeszukiwanie historii GIT pod kątem interesującego commita.

Jak widać możliwości są ogromne. Do wielu akcji, które obejmują wyszukiwanie tekstu możemy zaprząc fzf i ułatwić sobie życie!

Dla ułatwienia poszukiwań, zachęcam do rzucenia okiem na wiki fzf https://github.com/junegunn/fzf/wiki

Koherencja wiedzy

Mądrzy ludzie

Zagłębiając się w bibliografiach mądrych ludzi tego świata można dostrzec jedną, na prawdę zadziwiającą, rzecz. Wielu z nich, ba, większość z nich odznacza lub odznaczała się wiedzą z jednej strony głęboką, ale z drugiej strony też bardzo szeroką. Z jednej strony jest to banał, w końcu, właśnie dlatego uznajemy ich za szczególnych. Z drugiej strony można się zastanowić, jak ktoś kto miał te same 24 godziny podczas doby osiągnął wyniki diametralnie różne od innych?

Elon Musk

SpaceX CEO Elon Musk visits N&NC and AFSPC (190416-F-ZZ999-006) (cropped)
NORAD and USNORTHCOM Public Affairs / Public domain

Weźmy takiego Elona Muska. Mało kto odważy się zakwestionować jego umiejętności inżynierskie, ale z drugiej strony jest on też operacyjnym mózgiem i przedsiębiorcą stojącym za sukcesem firm takich jak PayPal, SpaceX czy Tesla. Spójrz na jego życiorys, tak na prawdę zaangażowany był w jeszcze więcej projektów!. Jeżeli spojrzymy na spektrum wiedzy potrzebnej do stworzenia tych trzech firm, branża finansowa, kosmiczna i samochodowa. To na prawdę niełatwe i niebywale zróżnicowane tematy. W jaki sposób Musk kultywuje dobre praktyki nauki? Ciekawą rzecz napisał w AMA (Ask Me Anything) jakie dał Reddit. Otóż wspomniał, że dla dla niego wiedza ma budowę drzewa gdzie dopiero gdy masz dobrze opanowane podstawy, czyli twój pień i grube gałęzie wiedzy, możesz zacząć dodawać cieńsze gałęzie i liście, nigdy na odwrót!

Leonardo da Vinci

Da Vinci Vitruve Luc Viatour
Leonardo da Vinci / Public domain

Innym przykładem może być, ikona i symbol „człowieka renesansu” czyli Leonardo da Vinci. Wystarczy spojrzeć na jego stronę na wikipedii: „włoski malarz, rzeźbiarz, architekt, filozof, muzyk, poeta, odkrywca, matematyk, mechanik, anatom, geolog”. Tak, to wszystko o jednej i tej samej osobie! To właśnie jemu przypisuje się cytat:

The noblest pleasure is the joy of understanding.

Leonardo da Vinci

Co możemy przetłumaczyć jako, „najszlachetniejszą przyjemnością jest radość zrozumienia”. Zauważ, że nie chodziło o radość wynikającą z tego, że wydajemy się mądrymi, nie chodziło o radość wynikającą z czytania, chodziło o radość ze zrozumienia!

Richard Feynman

Richard Feynman 1959
Unknown author / Public domain

Czytając książkę „Pan raczy żartować, panie Feynman!” rzuciło mi się w oczy jak wielką wagę Feynman przywiązywał do zrozumienia problemu a nie uczenia się formułek. Jak on to określił, nie można nazwać nauką przekładania jednego tekstu na drugi. Nie można nazwać nauką tłumaczenia terminu na jego definicję, bo nie prowadzi nas to do niczego co możemy potem spożytkować. Było to zwłaszcza widoczne podczas jego pobytu w Brazylii gdzie nie mógł się nadziwić tamtejszemu sposobowi edukacji i bezsensownością zakuwania formułek przez studentów. Najciekawszą w tym wszystkim jest to jak bliskie jest to moim doświadczeniom z polskim systemem edukacji.

Wjeżdża koherencja

W jaki sposób posiadając jedno życie, 24 godziny w ciągu doby, osiągnąć takie rezultaty by wszyscy uważali cię za kogoś o szczególnych umiejętnościach? Jak to się dzieje, że jedni nie mogą osiągnąć mistrzostwa w jednej dziedzinie, podczas gdy inni osiągają je w wielu dziedzinach? Jedną, chociaż na pewno nie jedyną, odpowiedzią jest silna koherencja wiedzy. Ten jeden czynnik pozwala na zastosowanie dźwigni i przekładanie efektów nauki z jednej dziedziny do drugiej.

Do słownika zaglądam rzadko 😛 Tym razem zdecydowałem się na ten krok. Co mówi SJP na temat tego czym jest koherencja?

„Koherencja – spójność wewnętrzna myśli, teorii lub ich wzajemna zgodność”. 

 https://sjp.pl/koherencja

Bardzo mi się podoba ta definicja! Problem w tym, że wydaje się nieco abstrakcyjna. Od siebie dodam jeszcze taką bardziej praktyczną:

Koherencją wiedzy możemy określić stopień w jakim nasza wiedza jest spójna i pełna. Im większa koherencja tym mocniejsze podstawy ma nasza wiedza oraz tym mniej w niej fundamentalnych braków. O wiedzy koherentnej mówimy wtedy gdy jesteśmy w stanie uczyć się poprzez wiązanie nowych faktów z wiedzą, którą już posiadamy. Traktujemy kolejne gałęzie wiedzy jako część całości a nie jako luźno powiązany zbiór faktów. Posiadamy wiedzę na temat natury rzeczy, nie tylko rozumiemy znaczenie poszczególnych elementów, ale i znamy powiązania między nimi.

Przykładowo wiemy nie tylko czym są wskaźniki finansowe takie jak P/E, CAPE czy EBITDA, ale także rozumiemy jakie są implikacje z ich zmiany. Dodatkowo potrafimy zrozumieć jak zmiany tychże wskaźników wpływają na wskaźniki finansowe przedsiębiorstw w okresie krótki jak i długim. Jesteśmy w stanie wyróżnić efekty pierwszego rzędu i efekty drugiego rzędu (eng. first-order effects and second-order effects) 

Koherencja w edukacji

Brak koherencji wiedzy to jeden z problemów dzisiejszej edukacji. Dlaczego? Obecne metody nauczania w szkołach są oderwane od rzeczywistości i praktyki. Ucząc się przede wszystkim abstrakcji w oderwaniu od praktycznej aplikacji nabywamy groźnego syndromu niespójnej wiedzy. Taka wiedza jest niesamowicie niebezpieczna z kilku powodów. Najważniejszym jest obniżenie motywacji do zdobywania nowej wiedzy. Tylko poprzez zdobywanie jednocześnie wiedzy praktycznej możemy widzieć rezultaty nauki, łatać luki w zrozumieniu konkretnych tematów i rozwijać się. To wszystko prowadzi też do złych nawyków, gdzie zdobywanie wiedzy jest celem samym w sobie i nie sprzyja umiejętności używania wiedzy.

green and black rope

Wiedza koherentna

Jakie są oznaki zdobywania wiedzy w sposób koherentny?

  1. Potrafimy wykorzystać zdobytą wiedzę w zdobywaniu praktycznych umiejętności
  2. Uczymy się znajdować analogie pomiędzy dziedzinami
  3. Przenosimy wiedzę z jednej dziedziny do drugiej
  4. Zdobywamy i rozwijamy modele mentalne  https://en.wikipedia.org/wiki/Mental_model
  5. Ucząc się budujemy podstawy na których kładziemy kolejne cegiełki dzięki czemu nie mamy do czynienia z chwiejną konstrukcją a specjalistyczną wiedzą i umiejętnościami.

W rezultacie kultywujemy zdrowe podejście w którym ciekawość prowadzi do chęci zdobywania wiedzy. Rozwijamy praktyczne umiejętności, a nauka daje rezultaty.

Black magic

Co jeżeli powiedziałbym ci, że zatrudnię dla ciebie kogoś kto pomoże utrzymać twój kod w pythonie w odpowiednim porządku? Ten ktoś zajmie się twoimi standardami. Jeżeli pracujesz w zespole programistycznym to znacznie ułatwi ci kooperację z innym, przyspieszy code review i ogolnie przyspieszy pracę. Przedstawiam Pana black https://github.com/psf/black robiącego tytułowy black magic

Początki

W najprostszym wypadku do użycia black magic wystarczy nam wywołanie prostej komendy:

black <<file name>>

Jeżeli nie masz jeszcze biblioteki to przedtem jeszcze:

pip install black

W rezultacie zobaczymy coś takiego:

Pozwoli nam na sformatowanie niechlujnego wyglądu kodu:

w coś co spełnia założone reguły:

Co potrafi Pan black?

Domyślnie black robi takie rzeczy jak:

  • standaryzacja użycia cudzysłowów
  • usunięcie zbędnych nawiasów np. z warunków if (condition):
  • usunięcie zbędnych pustych linii
  • umieszczenie argumentów wywołania funkcji, w miarę możliwości, w jednej linii
  • i wiele innych

Jak przystało na przydatne narzędzie black może być też konfigurowany tak by sprostać potrzebom ludzi pracujących z innymi standardami.

Przykładowo umieszczenie w pliku pyproject.toml:

[tool.black]
line-length = 75

zgodnie z intuicją sprawi, że nasz kod będzie przyjazny węższym ekranom:

Co jeszcze oferuje black?

  • Możesz skonfigurować integrację z systemem kontroli wersji i formatować kod przy użyciu pre-commit hooka.
  • Zignorować formatowanie części plików jeżeli nie chcesz do nich aplikować standardów
  • Użyć integracji z twoim ulubionym edytorem (Visual Studio Code, SublimeText 3, Vim, PyCharm)

Integracja z Visual Studio Code

Jako, że sam używam Visual Studio Code to pokażę, też w jaki sposób można z poziomu Visual Studio Code używać black. Wystarczy zrobić 2-3 proste czynności:

  1. Zakładam, że masz już zainstalowaną bibliotekę black. Jeżeli nie to pip install black.
  2. Do naszych ustawień visual studio code (plik settings.json) dodajemy wpis: "python.formatting.provider": "black"
  3. Za pomocą polecenia Format Document hmmm… formatujemy dokument 😉 Można też użyć skrótu Shift+Alt+F

Jeżeli chcemy w jakiś sposób sparametryzować formatowanie black’a i użyć niestandardowych ustawień formatowania, to w tym samym pliku używamy np. "python.formatting.blackArgs": ["--line-length", "90"]

Profit

Chyba nie muszę pisać ile czasu może nam to zaoszczędzić, jeżeli porównamy to z ręcznym formatowaniem kodu 🙂 

Przenieś swój system do AWSa – krótki przegląd usług

AWS, czyli Amazon Web Services oferuje nam wiele usług, które możemy połączyć w zestaw realizujący zadania przed nim postawione. Wykorzystując już kilka z najpopularniejszych narzędzi, np. Lambda, RDS, VPC czy też S3 jesteśmy w stanie stworzyć zaawansowany system, nie wymagający armii ludzi odpowiedzialnych za infrastrukturę.

AWS Free Tier

Mało tego, dzięki programowi AWS Free Tier możemy znacząco obniżyć koszty funkcjonowania systemu w pierwszym roku korzystania z wielu usług, a warto zaznaczyć, że część z tych benefitów pozostaje po 12 miesiącach.

Cennik

Przy decyzji o wyborze oferty konkretnego dostawcy usług w chmurze warto przestudiować cennik pod kątem usług które zamierzamy wykorzystać. Pierwszym krokiem jednak jest zaznajomienie się z usługami, które mamy do wyboru, a trochę ich jest.

Popularne usługi

EC2 (Elastic Compute Cloud).

To nic innego niż serwer wirtualny, który można wykorzystać w dowolny sposób do uruchamiania naszych i nie tylko naszych aplikacji. Często może być wykorzystywany jako forma przejściowa dla usług uruchamianych na naszych serwerach, które chcemy przenieść do chmury. Podstawowymi plusami EC2 są: możliwość auto-skalowania, dostosowywania typu maszyny do software-u który będziemy na niej uruchamiali (optymalizacja pod kątem mocy obliczeniowej, pamięci RAM, GPU bądź też operacji dyskowych I/O). Płacimy za wykorzystany czas.

Lambda

Jest to niewielka (zazwyczaj) aplikacja mogąca wykonywać operacje w przypadku wystąpienia jakiegoś zdarzenia. Skąd się bierze to zdarzenie? Jest publikowane przez inną usługę i w zależności od tego przez jaką to inny jest też charakter tej wiadomości. Przykładowo, możemy mieć do czynienia z informacją o nowym obiekcie w usłudze S3 czy też zmianą elementu w tabeli. Potrzebujesz wywołać pewną operację w określonym czasie, z określonym interwałem? Także tutaj, nie ma problemu.

RDS (Relational Database Service)

Usługa za pośrednictwem, której mamy dostęp do relacyjnej bazy danych. Jakie silniki mamy do wyboru? Od MS SQL Server, Oracle i MySQL do MariaDB, PostreSQL i Amazon Aurora. A dlaczego używać RDSa zamiast własnego serwera z bazą danych? Amazon ułatwia nam zarządzania poprzez możliwość łatwiejszego skalowania, backupowania czy też patchowania.

VPC (Virtual Private Cloud)

Wszystko to co związane z sieciowością. Możemy tworzyć tu nasze sieci, podsieci, VPNy, grupy bezpieczeństwa, tablice routingu oraz wiele więcej 🙂 

ELB (Elastic Load Balancer)

Dzięki tej usłudze podzielimy zapytania do naszej aplikacji. Po co? W celu zapewnienia niezawodności oraz określonej wydajności naszego systemu. 

DynamoDB

Zarządzana baza danych typu NoSQL. Nie martwisz się o brak miejsca, cache, enkrypcję. Jeżeli struktura danych w twojej aplikacji na to pozwala to DynamoDB może być ciekawą alternatywą dla RDSa.

S3 (Simple Storage Service)

Można o tej usłudze myśleć jako o serwerze FTP. Umieszczamy tu wszelkiego rodzaju pliki, w przypadku aplikacji webowych możemy tu hostować np. obrazki czy mp3 do pobrania przez użytkowników. 

SNS (Simple Notification Service)

Niby „prosty” z nazwy serwis, ale pozwala na wiele sposobów rozgłaszania wiadomości. Dzięki niemu zrealizujemy powiadomienia SMS, e-mail czy też opublikujemy zdarzenie dostępne dla usługi Lambda.

SQS (Simple Queue Service)

Kolejka dla twoich aplikacji. Pozwala na komunikację między usługami poprzez wysyłkę wiadomości. Komponent produkujący wysyła wiadomości na kolejkę i wraca do przetwarzania. Komponent konsumujący przetwarza wiadomości i zdejmuje je z kolejki.

API Gateway

Swego rodzaju fasada stojąca pomiędzy klientami twojego API a twoim systemem. W najprostszym wypadku integrujemy API Gateway z Lambdą i mamy działające API bez potrzeby stawiania jakichkolwiek serwerów. API gateway może zapenić cache, wersjonowanie czy też łatwe zarządzanie definicją zasobów dostępnych poprzez API.

Cognito

Zarządzanie użytkownikami naszego systemu. Pozwala na autoryzację przy pomocy Facebooka i Googla. Ogromną zaletą jest prosta integracja z innymi serwisami np. API Gateway.

Cloud Formation

Serwis pozwalający na tworzenie zasobów w innych serwisach. Zasada jest prosta, w Cloud Formation mamy możliwość opisu i setupu innych serwisów. Wszystko w jednym miejscu.

Cloud Watch

Centrum monitoringu naszego systemu. Możemy tu sprawdzać status alertów, metryki czy też logi z innych serwisów AWS.

Cloud Trail

Akcje wywoływane przez użytkowników pozostawiają po sobie ślad. Nie wiesz kto usunął twoją bazę danych? Sprawdzisz to w Cloud Trail!

IAM (Identity and Access Management)

Pozwala na zarządzanie użytkownikami, kluczami (KMS – Key Management Service) i dostępem do określonych zasobów (przy użyciu polityk)

Iceberg, Antarctica, Cold, Arctic, Snow, Nature, Frozen

Czubek góry

To oczywiście tylko czubek góry, AWS posiada ogromną bazę serwisów i pracując na co dzień z AWS sam odkrywam często serwisy o których wcześniej nie słyszałem. W następnych wpisach postaram się przybliżyć więcej z tej bazy serwisów.

Chmura obliczeniowa – dlaczego? Zalety i wady

Cloud computing to często pojawiający się temat w dyskusjach o miejscu prowadzenia swojego biznesu w chmurze. Jednakże, przed podjęciem decyzji o wskoczeniu do AWS, Azure czy Google Cloud, warto zaznajomić się z konsekwencjami takiego wyboru.
Przygotowałem zestawienie, które może pomóc osobom borykającym się z dylematem co do wejścia na chmurę.

Zalety

  1. Niski próg wejścia. Jest to niezwykle istotne zwłaszcza w przypadku startupów nie przynoszących jeszcze zysków. Jesteśmy w stanie zaproponować i zwalidować nasze MVP (Minimum Viable Product) często nawet zerowym kosztem. Przykładowo AWS oferuje nam AWS Free Tier – https://aws.amazon.com/free/ a Azure https://azure.microsoft.com/pl-pl/free/
  2. Bezpieczeństwo dostępu do danych. O ile używamy usługi w chmurze w rozsądny sposób mamy do dyspozycji mechanizmy dzięki którym możemy w nocy spać spokojnie. Oczywiście należy być świadomym, że dane nie leżą u nas „na serwerze pod biurkiem” tylko są w bliżej nieokreślonym miejscu w chmurze i to po naszej stronie stoi odpowiedzialność za kontrolę dostępu do danych czy też ochrona haseł.
  3. Mniej kodu związanego z infrastrukturą. Używamy infrastruktury udostępnionej dla nas i możemy skupiać się na tym co jest istotne dla naszego systemu. Dzięki chmurze rozpowszechnił się popularny trend serverless.
  4. Brak potrzeby własnych serwerów. Poza finansowymi aspektami związanymi z zakupem, nie musimy się przejmować awariami tego sprzętu czy też serwisowaniem.
  5. Łatwa skalowalność. W zależności od konkretnej usługi często może dziać się automatycznie w zależności od aktualnego obciążenia systemu. Co to znaczy dla naszego biznesu? Jeżeli obłożenie jest nierównomierne w czasie (a zazwyczaj tak jest) to możemy cieszyć się niższymi rachunkami w czasie mniejszego obciążenia i jednocześnie być w stanie obsługiwać nawet kilkunastokrotnie zwiększone zapotrzebowanie na zasoby.
  6. Dostępność. Dzięki zarządzanym serwisom ciężar utrzymywania wysokiej dostępności jest w wielu aspektach zapewniany poprzez dostarczyciela usług w chmurze. SLA jest zazwyczaj na wysokim poziomie, zadowalającym dla 99% systemów. W przypadku systemów gdzie dostępność jest na prawdę rzeczą krytyczną można stosować podejścia zmniejszające ryzyko takie jak wykorzystanie więcej niż jednego dostawcy usług chmurowych.
  7. Koszty proporcjonalne do wykorzystania zasobów. W zależności od serwisu możemy dostosowywać koszt systemu poprzez zmianę parametrów wykorzystywanych usług takich jak przydział CPU, RAM, wielkość dysku. W przypadku innych serwisów możemy mieć możliwość płatności tylko za wykonaną pracę, czyli liczbę (mili)sekund w których nasz kod był wykonywany.
  8. Łatwe backupy. Tworzenie kopii zapasowych w przypadku baz danych, plików jest znacząco ułatwione, a serwisy często udostępniają możliwość eksportu danych do plików przechowywanych w innych usługach.
  9. Wielorakość serwisów pozwalających na wykorzystanie funkcjonalności: 
    1. Uruchamiania kodu w formie bezstanowych serwisów (np. Azure Functions, AWS Lambda) bądź też wirtualnych serwerów (np. Azure Virtual machines, AWS Elastic Compute Cloud – EC2)
    2. Baz danych (np. AWS RDS, DynamoDB, Azure Cosmos DB)
    3. DNS (np. AWS Route53, Azure DNS)
    4. CDN (np. AWS CloudFront, Azure Content Delivery Network)
    5. Serwer plików
    6. Fulltext search
    7. Kolejki wiadomości
    8. Wysyłka wiadomości
    9. Code integration/deployment
    10. Konteneryzacja (Docker)
    11. Big data i hurtownie danych, zarówno w procesie zbierania, przesyłania, przetwarzania jak i przechowywania danych
    12. Analiza danych
    13. Machine learning
    14. Zarządzanie, konfiguracja i monitoring naszych usług
    15. Internet of Things
    16. Usługi multimedialne 

Wady:

  1. Bezpieczeństwo danych. Tak tak, podobny punkt był też w zaletach 🙂 Brak kontroli z naszej strony co do tego w jaki sposób nasze są przetwarzane. W pewnych aspektach opieramy się na zaufaniu co do dostawcy usług chmurowych.
  2. Koszty
    1. Potrzebna jest ciągła analiza i kontrola kosztów tak by szybko identyfikować miejsca w których pieniądze zbyt szybko są spalane. Na szczęście mamy do dyspozycji narzędzia dzięki, którym nie wymaga to nie wiadomo jakiego nakładu pracy.
    2. Architektura systemu musi być rozwijana w oparciu o analizę przyszłego rozwoju projektu tak by dobrać odpowiednie rozwiązanie które spełnia wymagania i nie jest zbyt kosztowne.
  3. Vendor lock-in. Im więcej używamy usług danego dostawcy tym łatwiej dobrać kolejną usługę tego samego dostawcy (dzięki łatwej integracji między nimi), a tym samym tym bardziej jesteśmy uzależnieni od dokładnie tej chmury.
  4. Brak kontroli i uzależnienie od dostawcy. Nie mamy kontroli co do decyzji podejmowanych przez dostawcę usług chmurowych, który w jednej chwili może zdecydować o:
    1. likwidacji jednej z usług na której my polegamy
    2. wycofaniu się z interesu
    3. znaczącym podwyższeniu cennika usług
  5. Bezradność po wystąpieniu awarii. Jeżeli odpowiednio nie przygotujemy się na problemy z dostępnością danego serwisu to w przypadku wystąpienia danej trudności nie możemy już zbyt wiele zrobić niż czekać i przepraszać naszych klientów.
  6. Ochrona danych osobowych. Wiele z przepisów obowiązujących w danym kraju może obostrzać naszą swobodę w zakresie co do tego gdzie i w jaki sposób te dane mają być przechowywane.

Ogólny bilans, moim zdaniem, wychodzi zdecydowanie na plus. W generalnym rozrachunku przejście na zarządzane usługi z których składamy nasz system jest po prostu tańsze, jeżeli podejdziemy do tego tematu umiejętnie. Go cloud!

Mikroserwisy – wprowadzenie i dlaczego chcesz je mieć

Architektura mikroserwisów

Podział systemu na mikroserwisy jest to styl projektowania w którym dzielimy funkcjonalność na niezależnie deployowalne serwisy. Każdy z tych serwisów odpowiada za część funkcjonalności systemu, są one często usytuowane na różnych maszynach a komunikacja między odbywa się najczęściej przez HTTP/REST API lub też przez wiadomości przesyłane pomiędzy nimi. Nasuwa się pytanie po co? Po to by ułatwić sobie życie, wyeliminować nieprzespane noce związane z wielkimi i ryzykownymi wdrożeniami oraz by móc powiedzieć, że stosujesz mikroserwisy. Z doświadczenia wiem, że każdy z tych argumentów jest niesamowicie ważny i sprawia, że nie będziesz chcieć wracać do „starego” podejścia.

Wśród najczęściej wymienianych firm wykorzystujących z sukcesami mikroserwisy wymienia się takich potentatów jak: Uber, Netflix czy też PayPal.

Netfix

Uber

PayPal

Architektura oparta o mikroserwisy powinna charakteryzować się tym, że każdy z jej elementów jest luźno powiązany (loosely coupled) z innymi. Tak tak, powinna, lecz „sprawny” programista może ukryć zależności przed niewprawionym okiem i dalej tkwić w monolicie. Tutaj też potrzebny jest stały wysiłek by utrzymywać luźne powiązania, to nie silver bullet (niespodzianka!). Dzięki temu zmiany mogą być wprowadzane niezależnie, przez różne zespoły w różnych częściach systemu.

Wymóg tego by każdy mikroserwis mógł być niezależnie deployowalny jak i to, że ma być luźno powiązany z innymi powoduje, że chcemy też unikać ukrytych zależności takich jak współdzielenie baz danych pomiędzy mikroserwisami. Każdy mikroserwis powinien mieć swoją bazę danych. Taki wymóg oczywiście niesie za sobą konsekwencje i musimy zapewnić spójność danych pomiędzy wieloma serwisami.

2017-07-24 20_42_50-BlogGD - microservices pt1.png - Paint

Co zyskujemy?

Jakie są zalety takiej architektury? Na początku nie byłem świadomy ich istnienia, zaraz po ich poznaniu lista zalet to były po prostu obietnice. Teraz, po latach spędzonych na pracy nad mikroserwisami widzę, że nie były to puste obietnice.

1. Każdy serwis może być osobno rozwijany.

Wybór technologii dla jednego serwisu często (ale nie zawsze) nie narzuca technologii dla współpracujących serwisów. Mikroserwisy komunikujące się przez HTTP/REST są tu szczególnie łatwe w izolacji. Przykładowo w projekcie nad którym obecnie pracuję wykorzystujemy mikroserwisy w językach c#, python czy też javascript. Umożliwiamy dzięki temu eksplorację innych technologii poprzez wykorzystanie jej np. w jednym z mikroserwisów. Dzięki tego typu architekturze takie eksperymenty, nawet w wypadku nie do końca pozytywnych rezultatów, nie rzutują negatywnie na cały system.

2. Drastyczne skrócenie interwału pomiędzy releasami.

Dzięki możliwości osobnego wdrażania pojedynczych mikroserwisów, taki release jest zarówno mniej ryzykowny jak i częstszy. Jeden deploy? Dzień jak codzień. 3 deploye? Czemu nie? 5+ deploymentów? Bywa i tak 🙂

3. Zmniejszenie złożoności.

System, poprzez zmniejszenie powiązań między poszczególnymi jego częściami charakteryzuje się mniejszą złożonością co wpływa m. in. na błędogenność i czas jego życia. Architektura monolitu ma tendencje do niekorzystnego spadku produktywności rozwoju na dalszych etapach trwania projektu. Mikroserwisy „zrobione dobrze” są bardziej odporne na próbę czasu przede wszystkim z racji lepszej enkapsulacji logiki, możliwości łatwiejszej izolacji problemów, a także wymuszenia lepszej modularności systemu.

4. Skalowalność.

Umożliwienie skalowania poprzez zwiększanie liczby instancji danego mikroserwisu. Jeżeli zidentyfikujemy mikroserwis, który jest wąskim gardłem w naszym systemie możemy zwielokrotnić liczbę jego instancji poprawiając tym samym wydajność całego systemu. Nie jest to coś co otrzymujemy „za darmo”. Wymaga to odpowiedniej kultury devopsowej. Ba, w moim obecnym projekcie po dłuższym czasie nadal nie wygląda to tak jak powinno. Na szczęście coraz popularniejsze wykorzystanie usług chmurowych upraszcza wprowadzenie skalowalności znacząco! Przykładowo AWS EC2  czy też AWS ECS .

5. Bardziej naturalny podział pracy.

Lepsza alokacja zasobów, łatwiejszy podział prac i zwiększona odpowiedzialność zespołów za serwisy, którymi się opiekują to następne z zalet tego podejścia do projektowania systemu. Architektura monolityczna w której odpowiedzialność jest bardziej rozmyta nie sprzyja efektywnej pracy.

6. Circut breaker.

Jeżeli coś nie działa to jest duża szansa, że reszta systemu jest w stanie działać mimo to. Jak uzyskać tego typu niezawodność? Możemy wykorzystać tu podejście w którym definiujemy pewnego rodzaju komponent, który przy odpytywaniu zależności, którą jest inny mikroserwis, a właśniwie jego API, kontroluje stan zdrowia tego API. Jeżeli stan zdrowia przez kilka kolejnych zapytań nie jest zadowalający, przykładowo brak jest połączenia z serwisem, bądź zwraca on HTTP 500 możemy zdecydować o wyłączeniu funkcjonalności jaką oferuje. Dzięki temu nie odpytujemy na darmo serwisu który być może tylko tymczasowo jest niedysponowany oraz dajemy użytkownikowi szansę skorzystania z innych funkcjonalności systemu.

Oczywiście lista zalet nie wyczerpuje w pełni tematu, gdyż architekturę mikroserwisów można zrealizować na różne sposoby przez co możemy uzyskać nieco inny ich zestaw. Osobiście wydaje mi się, że zmniejszona złożoność systemu to największy plus gdyż jest to istotny czynnik który wpływa na opłacalność projektów, a nadzwyczaj często jest niedoceniany.

Bibliografia i inne ciekawe materiały: