S čím pracujeme?

V této sekci budeme postupně přinášet náš vlastní pohled, názor a zkušenosti na technologie, produkty a nástroje, se kterými jsme přišli do styku.

Gradle

Gradle slouží pro buildování projektů a ve spojení s dalšími nástroji i pro udržování závislostí projektu na dalších knihovnách. V ETN jsme dlouhé roky pro buildování používali Ant, s vlastními rozšířeními pro snazší správu cizích i vlastních knihoven, včetně několika specifických pluginů do Eclipse. Díky nim byl problém udržování závislostí zvládnutelný a nebyl tak příliš velký tlak na změnu.

Přesto jsme tak nějak věděli, že “to není úplně ono”. A tak jsme věnovali nějakou pozornost systému Maven, který tehdy byl víceméně v plenkách. Přesnější čas už je těžké dohledat, ale rozhodně to je více než 5 let. Po prozkoumání našimi “technologickými skeptiky” jsme se rozhodli jej neadoptovat, přišel nám příliš těžkopádný, svazující a s nepříliš dobrou architekturou.

Začátkem roku 2011 se začínal nový velký projekt na dosud nepoužívaných technologiích. Interní pluginy už na správu jeho závislostí nestačily, vybrali jsme si proto Apache Ivy a pro buildování tehdy relativně neznámý Gradle, který nám měl pomoci nové úkoly automatizovat.

Myšlenky, na kterých byl Gradle postaven, se nám zamlouvaly podstatně více než u ostatních nástrojů. Prošli jsme si s ním cestu od prvních poměrně nestabilních verzí a nakonec ho víceméně úspěšně zavedli do firemní praxe. V tuto chvíli se zdá, že to byla dobrá volba a že je skutečně lepší a perspektivnější než Maven.

Hlavní výhodou Gradlu je to, že je postaven na principu DSL - domain specific language, což je vlastně specializovaný skriptovací jazyk. Skript tedy není oproti tradičnímu Antu nebo Mavenu čistě deklarativní, ale tvoří kombinaci deklarativních a imperativních (programových) konstrukcí.

Asi každý, kdo psal rozsáhlý build skript v Antu nebo Mavenu, narazil na problém konfigurovatelnosti či škálovatelnosti, který se pomocí deklarativních konstrukcí těžko řeší. Často to končilo málo elegantními a těžko udržovatelnými skripty, či dokonce copy-pastováním velkých částí kódu. V Gradle se tomu můžeme vyhnout tak, že takové problematické části logiky naprogramujeme.

  • Jednoduché věci dělá jednoduše, protože má pro základní nastavení rozumně definované defaulty.
  • Mocný skriptovací jazyk, dá se v něm programovat. Nepotřebuje miliardu pluginů na každou drobnost, tak jako třeba Maven.
  • Spoléhá na výbornou integraci s Antem. Věci, které umí Ant, můžeme přímo zavolat i v Gradlu pomocí speciálního API.
  • Dá se dobře rozšiřovat psaním vlastních pluginů, což jsou jakési kostry build skriptů. Tím se vyhneme složité údržbě zkopírovaných build skriptů na podobných projektech. Napsání konfigurovatelného pluginu ale už je trochu pokročilá záležitost.
  • Má velmi slušnou integraci s Eclipse (classpath container nebo generovanou classpath).
  • Detailní dokumentace.
  • Poměrně dlouhá učící křivka, dá se ale kompenzovat sdílením znalostí ve firmě. Jednoduché věci lze zvládnout rychle, se složitějšími nuancemi (které by byly nejspíš problematické i v jiných nástrojích) pomůže zkušenější kolega.
  • Groovy kód je stručný, ale dokáže být dost kryptický, takové jsou někdy i chybové hlášky. Problematický debugging. Často je značný problém najít příčinu chyby, a dohledat v referenční dokumentaci, jak to má být správně, a to i v případě triviálních chyb.
  • Gradle se stále vyvíjí, starší skripty často v novější verzi přestanou fungovat. Toto se naštěstí s novými verzemi výrazně zlepšuje.
Používáme zhruba od začátku roku 2011.
Spring

Jedná se o lightweight open-source framework pro vývoj Java EE aplikací. Zajišťuje dependency injection, řízení transakcí, IoC kontejner pro flexibilní konfiguraci a provázání částí aplikace. Přirozeně vede k programování vůči rozhraním a vhodnému návrhu aplikace, ve kterém lze snadno testovat jednotlivé komponenty. Poskytuje podporu pro všechny vrstvy aplikace - od persistentní vrstvy, přes aplikační logiku na serveru a remoting komunikaci po MVC model ve webové vrstvě (Spring MVC). Mnoho usnadňujících knihoven frameworku dokáže zajistit větší produktivitu. Framework se stal de facto standardem pro vývoj EE aplikací v Javě.

  • Jednotlivé moduly (knihovny) jsou samostatně použitelné, stejně tak jednotlivé utility jsou použitelné samy o sobě - lze využívat jen některé nebo všechny části frameworku.
  • Je neinvazivní. Pracuje s POJO objekty, nenutí implementovat specifická rozhraní, snadno lze používat vlastní již existující třídy.
  • Běží nejen na aplikačních serverech, ale i na populárních servletových kontejnerech, nenutí používat specifickou platformu.
  • Nabízí podporu pro Test Driven Development (TDD): Tvorbu testovacích kontextů, jednotkových a integračních testů.
  • Je velmi dobře zdokumentovaný a rovněž samotný kód knihoven je přehledný a poskytuje nejednu inspiraci.
  • Podpora aspektově orientovaného programování (AOP).
  • Vestavěná podpora pro Hibernate, snadná integrace s mnoha dalšími často používanými knihovnami (např. Quartz).
  • Podpora anotací pro dependency injection dále zjednodušuje a zpříjemňuje vývoj aplikací.
  • Zjednodušuje použití řady EE technologií: JDBC, JPA, JTA, JMX, JMS, remoting (RMI, Hessian, Burlap, Spring WS), ale i typických Java API jako je např. zasílání e-mailů.
  • Existuje mnoho podprojektů usnadňujících další oblasti tvorby aplikací: Spring Web Services, Spring Batch, Spring Security, Spring Web Flow, Spring LDAP, Spring Data. Množství dalších podpůrných projektů utěšeně narůstá.
  • Je poměrně jednoduché integrovat framework i s vlastními řešeními.
  • Framework byl prověřen mnoha firmami a širokou komunitou uživatelů.
  • Springová konfigurace pomocí XML byla převzatá do řady dalších knihoven, kde ji lze navíc různé rozšiřovat. Např. Apache CXF knihovna pro webové služby.
  • Občas třídy s velmi dlouhými názvy, ale alespoň je jasné, k čemu slouží.
  • Některá řešení každému nesednou (např. tvorba WS pomocí Spring WS). Framework má na všechno odpověď, unifikuje použití mnoha technologií, ale to nemusí být v jednotlivých případech vždy optimální.
  • Spring MVC se nehodí na všechny typy webových aplikací, je třeba zvážit i vhodnost jiných webových frameworků - nicméně i s nimi se framework typicky dokáže snadno integrovat (např. Spring + Wicket, Spring + GWT, Spring + JSF).
  • Není jednoduché se v tak rozsáhlém frameworku kompletně zorientovat, ale to není naštěstí vždy nutné - lze používat jen vybrané části, které se pro aplikaci hodí a programátor si je už osvojil.
  • Ve Springu existuje řada diametrálně odlišných postupů, jak dosáhnout požadovaného výsledku, díky čemuž je někdy matoucí výklad některé dokumentace a nebo případné nalezení řešení určité situace nemusí být použitelné, pokud již v aplikaci pracuji s jiným způsobem použití Springu.
Používáme v průběhu posledních pěti let, nicméně s frameworkem jsme pracovali už dříve.
Git

Jedná se o distribuovaný verzovací systém, který byl vytvořen pro potřeby vývoje linuxového jádra. Autorem je Linus Torvalds. Důraz je kladen na rychlost celého systému. Git je silný především při práci s větvemi, které reprezentuje jako ukazatele na jednotlivé commity. Pro nás důležitou skutečností při výběru verzovacího systému byla dostupnost vhodného pluginu pro Eclipse. Řešení se našlo v podobě pluginu EGit, který je pro základní použití naprosto dostačující. S náročnějšími úkony je pak vhodné do vývoje zapojit i řádkového klienta. Pro ty, kteří nepoužívají Eclipse a ani si nechtějí pamatovat složitější příkazy, existuje celá řada klientů poskytujících grafickou nadstavbu příkazovému řádku.

Při použití Gitu není uživatel nucen pracovat pouze jedním způsobem. Existuje celá řada osvědčených i méně tradičních workflow, mezi kterými můžeme vybírat.

Pro správu gitovských repositářů v současnosti používáme prostředí GitLab, dřívější řešení se opíralo o projekt Gitolite.

Pro použití Gitu mluví také fakt, že velké množství známých projektů je verzována právě v Gitu.

  • Složitější pro nové uživatele na pochopení. Zvláště pak pro ty, kteří již pracovali v jiných verzovacích systémech.
  • V příkazové řádce nejsou oddělené základní a pokročilé příkazy.
Začali jsme používat v roce 2011.
akka

Production-ready knihovna pro psaní distribuovaných aplikací, která díky actor modelu nabízí daleko jednodušší způsob návrhu paralelního zpracování než klasické synchronizační mechanismy v Javě. Aktoři jsou stavové komponenty, které vzájemně komunikují jen zasíláním immutable zpráv. Aktor nemůže přímo zasahovat do stavu jiného aktora, kód v rámci aktora je vykonáván v jednom vlákně, a synchronizaci tak není potřeba provádět. Aplikace se takto píší jiným způsobem, nicméně o návrhu aplikací založených na aktorech je daleko snazší uvažovat a výsledné aplikace budou typicky přehlednější a méně chybové než při použití synchronizačních primitiv z balíčku java.util.concurrency (není třeba mít obavy z nedostatečné/přílišné synchronizace a deadlocků).

Akka je velmi vhodná pro realizaci výkonných řetězců zpracování dat, cloudových řešení, nebo serverů, které obsluhují mnoho klientů. Komponenty distribuované aplikace lze izolovat tak, aby chyba v určité části aplikace neovlivnila jiné části aplikace. U selhávající komponenty lze provést recovery. Komponentám lze vyhradit samostatné pooly vláken tak, aby žádná z kritických částí aplikace nebyla výkonově ovlivněna jinými částmi.

  • Lze používat ve Scale i v Javě.
  • Na Acce lze s úspěchem postavit tasky pro paralelní zpracování dat, indexovací, vyhledávací a data transformující enginy, ale i celé frameworky řešící paralelně velké množství požadavků, příkladem může být výkonný Play! framework.
  • API knihovny staví na best practices pro tvorbu distribuovaných aplikací za pomoci aktorů, automaticky zabraňuje některým možných chybám.
  • Existuje framework pro testování vzájemné komunikace aktorů (přitom testovat distribuované aplikace není obecně vůbec jednoduché).
  • Jen změnou konfigurace lze z lokálního systému aktorů vytvořit systém distribuovaný mezi řadu výpočetních uzlů. Umístění jednotlivých aktorů je pro programátora transparentní, závisí jen na konfiguraci.
  • Počty obslužných vláken pro jednotlivé komponenty složené z aktorů lze rovněž dimenzovat v konfiguraci.
  • Aktoři jsou organizováni do hierarchie. V případě výpadku aktora může nadřízený aktor zajistit znovuobnovení subsystému.
  • Aktoři mohou dynamicky (programově) měnit topologii, přecházet od jednoho typu úkolu k jiným typům úkolů (implementovat stavové automaty), řídit vznik a zánik dalších aktorů a přemísťovat se do jiných lokalit.
  • Je třeba dávat pozor na vhodný návrh zasílaných zpráv a rozlišení typů zpráv. Dobrými programátorskými zvyklostmi lze případná rizika jako např. možnost zaměnění některých typů zpráv eliminovat.
  • Je třeba pamatovat na pokrytí obsluhy všech zpráv jednotlivými aktory, zajistit monitoring případných nezpracovaných zpráv.
  • Dostatečný prostor je třeba věnovat obnově funkčnosti aktorů, kteří např. z důvodu výpadků sítě přestali zprávy obsluhovat - nutnost implementace aktorů supervisorů.
  • Náročnější přechod na nový způsob tvorby distribuovaných aplikací. Nicméně při tvorbě rozsáhlejší distribuované aplikace se rychle zúročí.

Začali jsme používat v roce 2012.

Play!

Jedná se o poměrně jednoduchý MVC webový framework, postavený na principech RESTu, který nabízí propracované řešení pro tvorbu škálovatelných aplikací obsluhujících obrovské množství klientů. Přirozeně podporuje tvorbu asynchronních aplikací, které jsou bezestavové a neblokují cenné výpočetní zdroje. Nejen díky tomu je velmi rychlý při zpracování požadavků a snadno umožňuje horizontální škálování aplikace přidáváním dalších serverů.

  • Lze snadno integrovat s existujícími šablonovacími systémy, integrovali jsme do něj šablonovací systém interně používaný ve firmě. Rovněž do něj integrujeme vnitrofiremní profilovací a monitorovací řešení.
  • Interně používá Akku (Akka actor library). Díky tomu šetrně nakládá se zdroji, vlákna zpracovávající requesty po zpracování určité akce v aplikaci na nic nečekají a jsou hned k dispozici pro zpracování dalších akcí v rámci dalších requestů. Umožňuje nezávisle konfigurovat různé pooly vláken pro části aplikace, které by se neměly výkonově ovlivňovat. Výkon aplikace tak lze mít více pod kontrolou, z hardware lze při dobrém nastavení "ždímat" maximum výkonu.
  • Speciální vývojová konzole umožňuje hot-reloading tříd, provedené změny se v prohlížeči projeví hned po stisknutí klávesy F5.
  • Nativně podporuje psaní realtime webových aplikací, které v reálném čase zobrazují data, hned jak jsou na serveru k dispozici, nabízí také programovací model pro streamování dat.
  • Nabízí podporu pro zpracování formulářů, JSONu, asynchronní komunikaci s webovými službami, unit testy controllerů a šablon aj.
  • Snadné a přizpůsobitelné mapování URL na controllery.
  • Pro framework se snadno píší pluginy (stále vznikají další užitečné pluginy na http://www.playframework.com/modules).
  • Existuje verze pro Javu i Scalu.
  • Díky své jednoduchosti nemá vlastní podporu pro AJAX, nebo session data (snadno lze ale použít vlastní cache/storage).
  • Programové API pro Scalu nadužívá implicitní parametry a konverze, které mohou působit magicky, pokud programátor není s implicitním systémem Scaly obeznámen.
  • Nemá komponenty, nebo vlastní způsob kompozice stránek ze znovupoužitelných částí, jedná se o prostý MVC framework podobně jako Spring MVC. Hodí se tak zejména na veřejné weby s jasně definovaným grafickým designem, méně na intranetové aplikace.

Začali jsme používat a dále používáme s velmi pozitivním názorem od poloviny roku 2012.

Wicket
  • Vhodný pro aplikace, zejména rozsáhlé formuláře a tabulky.
  • Hodily se nám připravené komponenty.
  • Stáli jsme o hotovou integraci s Google Map Api.
  • Zkoušeli jsme nové technologie.
  • Řada předpřipravených komponent, validátorů...
  • Dobrá rozšiřitelnost komponent.
  • Snadná konfigurace či úprava core pomocí dědění.
  • Velká podpora AJAXu, včetně jQuery.
  • Oddělenost kódu (java) a šablony (html).
  • Možnost dynamického generování obsahu či obrázků.
  • Přímá podpora vícejazyčnosti.
  • Podpora CDI a Spring.
  • Snadná integrace s dalšími technologiemi.
  • Přímá podpora automatizovaného testování UI z java kódu.
  • Built-in debugovací nástroje, pluginy pro IDE.
  • Šetrnější na systémové prostředky vůči srovnatelným technologiím.
  • Vysoká bezpečnost.
  • Delší doba učení se s technologií.
  • Programátor musí bezpodmínečně pochopit principy komponent a modelů.
  • Některé UI věci je potřeba řídit či generovat z Java kódu (např. dynamické změny CSS, většinu AJAXu).
  • Nízká odolnost proti restartům serveru (násilné ukončení session).
  • Rozklad při loadbalancingu potřebuje sticky session nebo sdílení session mezi servery.

Použití Java kódu svádí programátory k zamotání business logiky do komponent Wicketu, ačkoliv by toto mělo být vždy jako samostatná vrstva. Rovněž používání anonymních vnitřních tříd, byť je v ukázkových případech, často není úplně optimální pro udržitelnost kódu. Vždy je třeba mít na paměti, že pokud jde něco díky technologii snadno udělat, musíme přemýšlet i nad tím, zda to půjde v budoucnu snadno měnit nebo dokonce znovu použít.

Začali jsme používat před dlouhou řadou let.

redis

Univerzální technologie, s kterou lze vyřešit různé druhy problémů:

PHP projekty - nahrazuje HTTP session.
Virtuální FS - pro vytvoření linku na soubor nám stačí pouze vědět, zda daný soubor existuje.

  • V databázi je klíčem cesta z adresářů, hodnotou je množina názvů souborů.
  • Snížení IO zátěže na serverech.
  • Oddělení aplikačních serverů od CDN (Content Delivery Network).
  • Zvýšení škálovatelnosti FS.
  • Dobrá dokumentace.
  • Jednoduché java API s intuitivním použitím: https://github.com/xetorthio/jedis
  • Rychlost odezvy - data jsou uchována v paměti.
  • Perzistence - RDB (snapshot datasetu), AOF (logovani write operaci).
  • Možnost konfigurace jako cache nebo store.
  • Master-slave replication.
  • Transakce.
  • Dobré datové struktury - pod klíčem může být uložen nejen jednoduchý řetězec, ale i složitější datová struktura: listy, hashe, sety, sorted sety
  • horší podpora pro Windows, při vývoji jsme raději použili databázi na linuxu.

Začali jsme používat začátkem roku 2013.