Mateusz na początku przedstawił ciekawą historię, odnośnie tego, dlaczego się zainteresował cache’m i kiedy został zdefiniowany standard JSR-107 - JCache. Fajnie się całość zbiegła z datami z filmu "Powrót do przyszłości", co prelegent dobrze wykorzystał na slajdach.
Mateusz bardzo fajnie przedstawił na diagramach sekwencji różne techniki działa cache'a:
- Cache Aside
- Read Through
- Write Through
- Write Back
- Write Behind
- Refresh Adead
Pierwsze trzy techniki z pośród wymienionych są zdefiniowane przez standard JSR-107, a pozostałe są wspierane dodatkowo przez niektóre implementacje.
Cache Aside jest najprostszy. Klient (aplikacja) sprawdza najpierw, czy wartość jest dostępna w cache’u. Gdy nie, to aplikacja sama odczytuje wartość ze źródła prawdy (dysku, bazy danych, etc.) i jeśli chce, to ją wrzuca do cache’a.
W metodzie Read Through to cache, a nie aplikacja kliencka, jest odpowiedzialna za odczyt wartości ze źródła prawdy i jej zapamiętaniu u siebie na później.
W podejściu Write Through to cache zapisuje wartość do źródła prawdy (synchronicznie) i zapamiętuje u siebie.
Write back zapisuje dane do źródła prawdy, dopiero wtedy gdy dana wartość jest usuwana z cache’a. Podejście to jest często stosowane w procesorach (L1, L2 cache) i wartości te mogą być niespójne ze źródłem prawdy (pamięć RAM). O unieważnieniu cache’a decyduje cache provider.
Przy Write behind klient zapisuje do cache’a i cache asynchronicznie rozpoczyna zapisywanie do źródła prawdy. Gdy w międzyczasie, ktoś będzie chciał odczytać wartości, to dostanie je bezpośrednio z cache’a.
W ostatniej metodzie Refresh Ahead cache decyduje podczas odczytu, czy wartość trzeba odświeżyć, czy nie.
Dalej było jeszcze o 3ch rodzajach operacji jakie mogą być wywoływane na cache’u:
- Pessimistic locking
- Lock free
- Optimistic locking
Bardzo fajna, mięsista prezentacja. Uwagi odnośnie sposobu prezentowania przekazałem wieczorem bezpośrednio Mateuszowi.
-XX:+UseG1GC, Jakub Kubrynski
Następnie Jakub Kurbyński ładnie omówił Garbage collector G1, który na być domyślny w Javie 9. Prelegent fajnie przeszedł przez to w jaki sposób jest zorganizowana pamięć w Javie i jakie to ma konsekwencje dla algorytmów odśmiecania. Stopniowo powoli odkrywaliśmy nowe pomysły w sposobach organizacji pamięci i algorytmów odśmiecających.
W G1 mamy wiele faz, ale dokładniej były omawiane 4:
- Young GC
- Concurrent cycle
- Mixed GC
- Full GC
Fajne było podsumowanie, jak tuningować G1. Najlepiej ustawić:
-XX:MaxGCPauseMillis=250lub na inną empiryczną wartość. Wtedy G1 będzie starał się nie przekroczyć zadanego czasu na odśmiecanie. Oczywiście gdy wartość będzie zbyt mała to się to nie uda. Złą stroną tuningu jest natomiast ten slajd:
czyli flagi których należy się wystrzegać ;)
Jeszcze inne dobre praktyki to:
A do przeglądania logów warto skorzystać z GCViewer, JVisualVM i Mission Control.
Nagranie z Confitury, polecam sobie obejrzeć:
Liquibase - zarządzanie zmianami w relacyjnych bazach danych, Marcin Stachniuk
W kolejnym slocie przyszedł czas na moją prezentację. Grono zainteresowanych było niewielkie, bo w drugiej sali w tym czasie mówili o mikroserwisach po raz 144. Slajdy (trochę zaktualizowane od ostatniego razu) poniżej.
Ze zmian (po za kolorkami dopasowanymi do konferencji) to istnieje łatwiejszy sposób na wprowadzenie Liquibase'a do istniejącego projektu, niż ten który przedstawiałem na WrocJUG'u. Można skorzystać z komendy changeLogSync, która to tworzy i wypełnia danymi z changelog'a tabele potrzebne do działania biblioteki (DATABASECHANGELOG i DATABASECHANGELOGLOCK), a same zmiany nie są wykonywane. Po więcej szczegółów zapraszam na stonę Liquibase'a: Adding Liquibase on an Existing project.
Drugą wartością dodaną do prezentacji jest moje subiektywne porównanie Flyway'a i Liquibase'a, ale kot nie był niech żałuje.
Java 9, Arkadiusz Sokołowski
Prelegent pokazał parę nowości które nas czeka w kolejnej wersji Javy. Było oczywiście o REPLu i modułach, czyli projekcie Jigsaw i jak to na nas wpłynie. Prezentacja była ok, ale gdzieś już coś o nowościach słyszałem...
Java developer meets AngularJS/JavaScript: real-world projects’ experiences, Marek Matczak
Prelegent pokazywał z początku popularność różnych języków programowania, gdzie górował JavaScript i Java. Marek proponował te dwa języki do obecnych projektów, a dokładniej Spring-Boot’a i AngularJS’a.
Prelegent przedstawił, jakie są możliwości połączenia tych dwóch światów, od strony budowania aplikacji. Jedno podejście, to łączenie części frontend'owej z buildem Maven’owym. Można do tego wykorzystać maven-assembly-plugin, który buduje zzipowaną aplikację kliencką, a później za pomocą exec-maven-plugin można uruchomić node.js’a. A całość do WAR’a można wrzucić za pomocą: maven-war-plugin’a.
Drugie podejście proponowane przez Marka to wykorzystanie exec-maven-plugin’a do budowania frontendu w trakcie fazy generate-sources. Zasoby te wrzucamy do src/main/resources/static, czyli tam gdzie standardowo Spring Boot się ich spodziewa.
Całość jest dostępna na GitHubie jako Open Application Standard Platform (OASP).
Z ciekawostek, które mi utkwiły, to warto się przyjrzeć Google JavaScript Style Guide i Idiomatic JavaScript, aby wiedzieć jak dobrze pisać kod w JavaScript’cie.
Warto też na przyszłość przyjrzeć się Isomorphic JavaScript. Dzięki temu, będziemy mogli wyrenderować stronę HTML po tronie backend'u, co pozwoli nam np. na szybsze ładowanie się strony głównej naszej aplikacji.
Muszę się również przyjrzeć Gulp’owi, gdyż on ma wbudowane reverse proxy.
Dzień 2
On-heap cache vs. Off-heap cache, Radek Grębski
Drugi dzień zaczął się bardzo mięsistą prezentacją na temat pamięci off-heap, czyli pamięci po za standardowym heap’em Javowym. Jest to pamięć, która nie jest zarządzana przez Garbage Collector, można w niej zapisywać tylko tablice bajtów (korzystająć ze standardowego API) i sami musimy zajmować się jej zwalnianiem.
Generalnie bardzo polecam tą prezentację, jest dostępne nagranie z Confitury 2015 jak i kod na GitHubie: https://github.com/rgrebski/confitura2015
Trochę podsumowując prezentację:
Aby zaalokować pamięć w Javie, można skorzystać z następujących klas: HeapByteBuffer (na stercie [heap], do 2 GB), DirectByteBuffer (po za stertą, do 2 GB), MappedByteBuffer (po za stertą, do 2 GB, pamięć perzystowana), Unsafe.allocateMemory() (więcej niż 2 GB).
Pierwsze 3 klasy mogą allokować do 2 GB ponieważ jako argument przyjmują int’a, który ich ogranicza. Bardzo ciekawą klasą jest MappedByteBuffer, która tworzy buffer w pamięci, który może być zapisywany do pliku na dysku. Ma on tą przewagę nad wszystkim innym, że w przypadku całkowitego crash’u maszyny wirtualnej zapis i tak się powiedzie. Operacja ta jest zapewniana przez system operacyjny.
Chcąc allokować pamięć większą niż 2 GB to już trzeba korzystać z Unsafe’a. Korzystanie z tej klasy nie jest łatwe i wygląda jakby sam Chuck Noris ją pisał. Właściwie ta klasa z definicji miała być dostępna tylko dla „zaufanego kodu”, czyli do wewnętrznego użytku przez Javę. Ale coś poszło nie tak i obecnie masa frameworków i bibliotek z niej korzysta. Co gorsza to klasa ma być niedostępna w Javie 9, więc będzie ciekawie. Sporo kodu trzeba będzie przepisać, albo znaleść haka, aby się dostać do odpowiedniego modułu.
Dalej było o Chronicle Map. Jest to mapa, która jest zapisywana po za stertą. Jest też perzystowalna, dzielona pomiędzy osobnymi procesami JVM (również po sieci). Jedynym minusem jest fixed size, tzn. musimy wiedzieć jak duże będą nasze obiekty. I tak dla String’ów i kolekcji musimy za pomocą @MaxSize zdefiniować jak maksymalnie długie będą nasze teksty i jak wielkie kolekcje w obiektach. Gdy przekroczymy granicę to dostaniemy błąd. Obiekty zapisujemy do bloków o stałej wielkości - trochę pamięci się marnuje, ale dostęp do niej jest łatwiejszy.
Dalej było sporo porównań szybkości działania Mapy i Chronicle Mapy. Następnie prelegent opowiedział jeszcze z grubsza o Hazelcas’cie i Redisie, które również porównał z Chronicle Map.
Purely functional data structures, Tomasz Kaczmarzyk
Na początku zaczęło się o tym jak w językach funkcyjnych są zaimplementowane Listy, że składają się z głowy i ogona, że ogon wykorzystuje dokładnie tą samą strukturę co pierwotna lista itd. Kto się uczył Skali, lub innego języka funkcyjnego, to na pewno kojarzy koncept.
Póżniej było już ciekawiej, o tym jak jest zbudowana kolejka w językach funkcyjnych, w której można dodawać elementy na końcu. W standardowej liście jest to bardzo kosztowna operacja. Kolejka wprowadza pewne ciekawe pomysły, jak może ona być wewnętrznie zorganizowana, aby efektywnie przeprowadzać operacje na niej, mi.in. dodawania elementu na końcu. Ten fragment prezentacji był bardzo fajny.
Następnie było o tym jak wewnętrznie jest zorganizowany Git i jaka to jest ładna struktura danych. Temat był mi już wcześniej znany, więc mnie aż tak nie zachwycił jak poprzednia część.
Prelegent miał bardzo fajne slajdy (pisane kredą po tablicy), z ładnymi animacjami przejścia.
Sane Sharding with Akka Cluster, Michał Płachta
Tutaj było mnóstwo programowania na żywo, które działało! Prelegent się dobrze do tego przygotował.
Na początek napisał pojedynczego aktora obsługującego jakieś zapytania i zrobił test wydajności. Następnie, razem z publicznością, udoskonalał rozwiazanie… Implementowaliśmy system rozdzielający paczki na taśmociągu w jakimś magazynie.
Jako drugi krok, prelegent dorzucił drugiego aktora, który tylko podejmował decyzję o przeznaczeniu paczki. Następnie pojawili się kolejni aktorzy i to już bardzo przyspieszyło obsługę zapytań. Na koniec był jeszcze przedstawiony Akka cluster, aby można było to łatwo skalować na więcej maszyn.
Kod z prezentacji jest dostępny tutaj: https://github.com/miciek/akka-sharding-example. Warto przejść sobie po commit'ach i zobaczyć jak się aplikacja rozwijała.
Recepta na retrospekcję z finezją, Wòjcech Makùrôt
Retrospekcje są wpisane w Agile Manifesto jako dwunasty punkt:
At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behavior accordingly.czyli:
W regularnych odstępach czasu zespół analizuje możliwości poprawy swojej wydajności, a następnie dostraja i dostosowuje swoje działania do wyciągniętych wniosków.Prelegent podał i opowiedział na przykładach swoje 10 punktów, które trzeba spełnić, aby mieć dobrą retrospektywę. Postaram się streścić, jak ja to zrozumiałem.
- Trzeba się dobrze przygotować. Spisać sobie plan spotkania, załatwić wszystkie niezbędne pomoce materialne, poszukać inspiracji, aby nie było nudno.
- Wprowadzamy jakiegoś IceBreak’era, aby rozmawiało się na luzie. Można odwrócić krzesła w sali, aby ludzie musieli zrobić coś innego. Prowadzący spotkanie (facylitator) może być niemerytoryczny - do niego należy moderacja i czasem pacyfikacja spotkania. Najważniejsze jest zdanie innych.
- Sprawdzamy, czy z poprzedniej retrospekcji udało nam się zrealizować jakieś postanowienia. Jeśli nic się nie udało, to powinniśmy przerwać i zastanowić się dlaczego się nie udało.
- Możemy opowiedzieć historyjkę, odnośnie tego co działo się w ostatnim sprincie. Budujemy przez to naszą wspólną świadomość.
- Grupowanie i priorytetyzowanie problemów - powinniśmy zajmować się tylko tymi najważniejszymi problemami.
- Dziel i rządź, czyli z którymi problemami jesteśmy zdolni sobie poradzić, i które będą miały największy wpływ na poprawę naszej sytuacji.
- Analiza przyczyn, dlaczego coś nie działa. Tutaj możemy skorzystać z metody 5x dlaczego, ość Ishikawy
- Planowanie naprawy, czyli: co trzeba zrobić, jak, kto będzie za to odpowiedzialny i na kiedy. Nie warto brać więcej niż 4 tematy do naprawy, bo to może być niemożliwe do zrealizowania.
- Celebracja tego do czego udało się dojść, czyli warto podziękować za współpracę, nagrodzić jakoś uczestników, wyjść na piwo...
- Śledzenie postępów w kolejnej iteracji, czyli sprawdzanie wykonania zadań.
Slajdy z wystąpienia:
Refactoring meets big money, Michal Gruca
Prelegent przedstawił 3 możliwe podejścia do refactoringu:
- Codzienny refactoring
- Pisanie całości od nowa
- Przepisywanie modułów i podmienianie
Warto też, przed pójściem do biznesu, trochę się przygotować. Można stworzyć jakieś prototypowe rozwiazanie i pokazać, że ono przynosi nam jakąś wartość. Przykładowo przyspieszymy build’a albo release’a.
Prelegent polecał do przeczytania fane case study, jak to Soundcloud przechodził na mikroserwisy.
Common fallacies of micro services, Marcin Matuszak
Prelegent w ciekawy sposób podszedł do tego, w jaki sposób obecnie są wynoszone pod niebiosa mikroserwisy, kontrargumentując potencjalne zalety jakie nam daje to podejście. I tak możliwość pisania każdego mikroserwisu w innym języku jest kiepski, bo jak ktoś napisze coś w bardzo egzotycznym języku (którego mało kto zna) i później się zwolni z pracy, to trzeba będzie nauczyć się tego języka, aby utrzymywać kod.
Monolityczne aplikacje wcale nie są takie złe. Są łatwe do pisania testów, w deploymencie i utrzymaniu. Jak rozmawiamy o mikroserwisach, to się skupiamy na tym, że mają być serwisy i że mają być małe. A zapominamy że mają sie komunikować po sieci, co przysparza masę dodatkowych problemów. Jeśli zepsuliśmy aplikację monolitową, to również i zepsujemy mikroserwisy.
Podsumowując całość, była to bardzo fajna konferencja, w końcu coś ciekawego i większego zawitało do Wrocławia. Nie miałem wysokich oczekiwań co do prelekcji, a okazały się one na dobrym poziomie. Byłem więc pozytywnie zaskoczony tą konferencją. Jednocześnie sam miałem okazję wystąpić i wyświetlać swoje slajdy po raz pierwszy na kinowym ekranie.