GeeCON Prague 2018
Po třech letech jsem zase zavítal na polskou konferenci GeeCON, která se konala 18. – 19. října v Praze. Přiznávám, že jsem se těšil až zjistím, kam se pozornost řečníků za ta léta posunula. GeeCON si drží svou úroveň kvality a po technické a organizační stránce jsem nebyl zklamaný. Celkově jsem si z konference odnesl pocit toho, že Java jako ekosystém se definitivně posunul v hype cycle do „plaeau of productivity“. Nenarazil jsem na žádného řečníka, který by zaslepeně vychvaloval nějakou technologii, aniž by přiznal slabá místa a racionálně uvedl místa, kde se vyplatí a kde se naopak nevyplatí daný přístup použít.
Hned na první přednáška byl live coding, ve kterém Oleh Dokuka provedl refactoring klasické Spring MVC web aplikace na reaktivní aplikaci ve Spring 5 a WebFlux přístupu. Byla to zajímavá ukázka toho, co „přepis“ aplikace do reaktivního přístupu znamená a jaké benefity to může přinést (optimální utilizace zdrojů, responsivita, odolnost proti výpadkům externích systémů, násobná výkonnost). Na druhé straně bylo také hezky vidět, že výsledný kód je mnohem náročnější na návrh, implementaci a porozumění (ačkoliv počet řádků je velmi malý). Zatím jsem přesvědčený o tom, že reaktivní programování se rozhodně nestane mainstreamem, ale bude volbou na místech, které tento přístup budou vyložene svými nároky požadovat. Zájemce bych odkázal na článek, který se přednášce v mnohém podobá. Jednou z doporučovaných serverů pro reaktivní programování byl Netty, pro komunikaci s databází vzniká alternativa k JDBC s názvem R2DBC, která se snaží dodat plně asynchronní konektory do tradičních relačních databází.
Stress driven development Dmitry Vinnika byla zajímavě pojatá přednáška člověka, který kvůli přepracování skončil v nemocnici. Popisoval věci, které ve svém životě po této příhodě změnil a proč si myslí, že kdyby je do své denní rutiny zařadil dřív, tak by v nemocnici vůbec skončit nemusel. Jeho rady se týkaly několika hlavních oblastí – spánku (8 hodin denně), stravování, zavedení pravidelného fyzického a mentálního cvičení a zdravých pracovních návyků. Přednáška byla nabitá různými tipy, hacky a odkazy na literaturu / podcasty. Doporučuji si ji už kvůli odkazům projít. Musím říct, že jsem rád, že tam zazněla celá řada věcí, které jsem si sám na sobě odzkoušel – ale jsem tak na půli cesty a v mnoha ohledech můj životní styl rozhodně zdravý není a občas se ptám, kdy na své limity narazím. Pár tipů, které mne zaujaly zmíním, ale nebudu je rozepisovat: mějte jediné místo, kde ukládáte informace, snažte se vždy zaměstnávat svou mysl jedním úkolem – multitasking je toxický, svůj vztek si vybijte na neživé věci a nikdy jej nepoužívejte proti partnerům, zaměřujte se v životě na to pozitivní, dodávejte lidem odvahu a inspiraci – chvalte je, připravujte si a vychutnejte si „tiché momenty“, kdy jste jen sami se sebou, poznejte sami sebe, zkuste každý den 10 minut meditovat, udělejte si ze sportu zvyk a potřebu, odměňujte se, začněte málem a teprve postupně zvyšujte laťku, dělejte různé pohybové aktivity, ať máte vybití pestré a těšíte se na něj, střídejte náročnou a vytrvalostní aktivitu, v práci se vyhněte rozptylování, zrušte si notifikace, umísťujte si mobil mimo dosah své ruky, navrhněte v kanceláři pravidla, která všem umožní soustředit se, minimalizujte online reakce – přejděte na asynchronní zpracování úkolů / dotazů, naučte sebe i ostatní, že asynchronní přístup je „norma“, vyhněte se nevyrovnaným výkonům – tj. jeden den 14 hodin, druhý den 4, z dlouhodobého pohledu je pro všechny výhodnější 100% nasazení po stejnou dobu každý den, dělejte svou práci s vášní, pokud vás nudí – změňte ji, stavte před sebe výzvy, najděte si komunitu, kde vám je dobře, kontribuujte do ní.
V další přednášce proběhlo pro mě zajímavé shrnutí aktuálního stavu Java platformy poté, co Oracle oznámil zpoplatnění Oracle JDK pro provoz v produkci. Je to téma, které bylo nedávno propíráno v řadě článků, ale jednoduchý přehled se mi dostal až tady na GeeCONu. V zásadě máme aktuálně jen dvě verze s dlouhodobým supportem – JDK 8 a 11, všechny verze mezi tím nedostávají další patche po uvolnění vyšší verze a to ani bezpečnostní. Pokud chcete tedy migrovat svoji codebase na vyšší verzi Javy, tak jedině na verzi 11. Jestli jsem správně pochytil roadmap, tak další LTS verze je plánována až verze 18. Mezi tím, budou každý 6 měsíců vycházet meziverze, kde budou uvolňovány novinky v Jazyce. Další zajímavou věcí pro mě je to, že OpenJDK a OracleJDK jsou kompilovány ze stejných zdrojových souborů a musí být tedy ekvivalentně kompatibilní, Oracle JDK obsahuje pouze některé další dodatečné enterprise nástroje a onen zmíněný support. Tj. provoz systémů na Open JDK by měl být bez větších problémů – co prozatím visí ve vzduchu je to, jak budou do OpenJDK propagovány bezpečnostní záplaty. Je dost možné, že budou dostupné pouze pro nejnovější verze a tudíž by provoz JDK zdarma na produkci představoval jisté riziko v tom smyslu, že bychom museli a) průběžně upgradovat i přes main verze (což zvedne interní náklady + riziko nekompatibility knihoven 3-tích stran) b) riskovat existenci chyb v samotném JDK, které se v čerstvých verzích mohou vyskytnout. Alternativou je samozřejmě provozování nějaké varianty se supportem, když už ne od Oracle, tak třeba od Red Hatu, Azulu a případně dalších vendorů.
Na konferenci bylo hned několik přednášek o Microservices, které soudě podle jejich obsahu prožívají právě období rozčarování (viz. v úvodu zmíněný hype-cycle). Řečníci ve shodě jmenovali řadu praktických zkušeností, kdy přechod na microservicy přinesl týmu jen nové problémy ve formě komplexních souvislostí, obtížného ladění, komplikovaného zajištění zpětné kompatibility a paradoxně i evoluce celého systému. Padaly tam zajímavé příhody ze života – jak třeba v systému desítek microservices trackovat, které jsou a které nejsou využívány? Podle počtu volání na tyto microservicy (tj. pokud na MS nepřišlo žádné volání víc jak několik měsíců, může se zrušit)? Existují například fallback servicy, jejichž účelem je být aktivní pouze ve chvíli, kdy hlavní systém vypadne a ty nejsou normálně provolávány. Pak může docházat k humorným situacím, kdy po dlouhé době dojde k výpadku hlavní služby a správně kód přesměrovává volání na fallback službu, která má celý systém zachránit v těžké chvíli a … ta také není v provozu, protože ji z důvodu neaktivity někdo z produkčního systému odstranil. Stejně tak se přechodem na microservicy tým zbaví základních stavebních kamenů, na které jsme v IT průmyslu zvyklí – transakčnost, konzistence se najednou řeší mnohem hůř. Značně komplikované je i správné nastavení error handlingu, monitoringu, deploymentu a dalších věcí. Tři řečníci se na závěr shodli na tom, že pokud nejste Netflix nebo podobná firma, která řeší skutečně velký traffic s relativně málo komplikovanou byznys logikou, je správně implementovaný monolit pro vás daleko lepší varianta provozu. Dobře implementované monolity vám umožní škálovat nahoru – jako příklad byl uváděn StackOverflow, který provádí mnoho deploymentů denně, zpracovává neuvěřitelné množství provozu a přesto je implementován jako monolitické řešení. Padla i věta, že správná modularizace řeší 90% problémů, kvůli kterým jsou v současné době nasazována řešení na microservisní architektuře. Moje vlastní zkušenosti z FG tohle jen potvrzují. Netvrdím, že všechno děláme správně – ale správná dekompozice do izolovaných JARů a isolace i na úrovni Spring kontextů (viz. moje přednášky o modularitě) nám umožňují rozšiřovat systém už celá léta. Odstranění deprekované funkcionality pro nás obvykle znamená pouze odstranění jedné složky (JARu) ze source repository, stejně tak nám skvěle funguje vývoj společné codebase v oddělených týmech … ale nechci zde zabíhat do detailů. Zároveň si nemohu být jistý, že ze mě nemluví confirmation bias.
Zabrousil jsem i na přednášku o implementaci GraphQL rozhraní v Javě pomocí knihovny GraphQL-Java, kde přednášející na živém kódu ukázal základní implementaci rozhraní v GraphQL a představil hlavní benefity tohoto formátu. Aktuálně Javová knihovna podporuje všechny základní prvky GraphQL: query, mutations i subscription. Implementace rozhraní není vůbec složitá, i když v konkrétních situacích může představovat i určitá rizika. Konkrétně se v ní problematicky řeší 1:N problém známý z ORM – tj. jak efektivně a obecně řešit situaci, kdy díky položenému GraphQL dotazu dochází k baráži persistentní vrstvy mnoha nezávislými dotazy, které by se daly optimalizovat z mnoha volání getById na jediné volání getByIds. Zdá se, že tato optimalizace v knihovně ještě dořešená úplně není. Taktéž se rozebíralo i riziko komplexních GraphQL dotazů, které by mohly DOSovat systém. Implementace v Javě má podporu pro omezení maximální komplexity Query, které bude možné v systému vyhodnotit (viz. toto issue). S použitím GraphQL rozhraní se vám ovšem zkomplikují možnosti cachovací logiky a věci jako autorizaci / autentizaci si budete muset také pořešit na koleně sami. Doba, kdy si vyzkouším své první GraphQL API se blíží a už se docela těším.
Pomalu se blížíme ke konci celé dvoudenní konference. Poslední přednáška, která ve mně zanechala silný dojem byla ta od Jaroslava Tulacha, ve které ukazoval, jak je možné využít native compiler, který je součástí projektu GraalVM pro vytvoření samospustitelného souboru ve strojovém kódu cílové platformy (tj. stejně, jako kdybyste zkompilovali kód v C). V rámci nativního kódu přitom zůstanou klíčové funkcionality JVM jako je třeba Garbage Collector, možnost remote debuggingu atp. Logicky v něm není hotspot, protože všechen kód je již zkompilovaný do nativního kódu, také ovšem přijdete o možnost reflexe nad třídami, která se dá do jisté míry nahradit vygenerováním deskriptorů, které napoví kompilátoru, že pro konkrétní třídy / fieldy / metody má zachovat dostupnost přes reflexní API. Výsledkem je binárka, která startuje neuvěřitelně rychle (binárka obsahuje i inicializační image, kde jsou již inicializované všechny statické inicializátory tříd), má daleko menší memory footprint než ekvivalent nad JVM a přitom si zachovává téměř stejnou rychlost jako Java samotná. V některých testech takto zkompilovaná aplikace vychází i 2-3 rychlejší než aplikace napsaná v Go. Zajímavá byla i možnost propojení Javy běžící ve JVM s druhou částí aplikace, která byla zkompilovaná do nativního kódu a využívá třeba i přímého volání C knihoven systému. Trochu mi to připomíná staré časy, kdy se z pascalu volal na důležitých místech přímo assembler, aby vývojář zajistit maximální výkon programu. V době lambda funkcí mi připadá, že tohle je zrovna technologie, která by stála za vyzkoušení.
Z poslední vtipně pojaté přednášce, která se snažila vyvrátit dogmata okolo test-driven-development jsem bohužel díky vlaku musel odejít před jejím koncem. Tomer Gabel se na konkrétních faktech snažil dokázat, že neexistují žádné tvrdé důkazy, které by podpořily tvrzení, že kód, který vznikne pomocí TDD je nějak výrazně lepší než kód, který vznikl stylem „test-last“ nebo „test-middle“. Že se jedná v podstatě o dogma, které se vývojáři neodvažují zpochybňovat, protože za ním stojí výrazné a známé osobnosti naší komunity. Vše souvisí už s tak základní věcí jako je ta, že se nedokážeme ani shodnout na tom, co představuje kvalitní kód – neexistuje žádná všeobecně uznávaná metrika, která by umožnila kvalitu kódu exaktně měřit a že většina technik stojí tak trochu na vodě (code-coverage, cyklomatická komplexita, množství metod ve třídě atd.). Neexistují žádné studie, které by prokazovaly, že TDD produkuje SW s menším množstvím chyb než BDD nebo jiné techniky používané pro vývoj SW s automatickými testy. Jediné, na čem se všechny studie shodují je to, že kód, na kterém probíhá systematické testování obsahuje ve výsledku menší množství chyb – což by selským rozumem došlo asi každému :)
Zkrátka a prostě jsem nabyl dojmu, že letošní GeeCON byl ve znamení boření mýtů a dogmat a pragmatického přístupu k věcem. Rád si přečtu i názory dalších kolegů – na konferenci jsem potkal celou řadu zajímavých lidí a doufám, že si také najdou čas na sepsání svých dojmů. Namátkou třeba @Musketyr, který přednášel o frameworku Micronaut, který právě na microservisy cílí.