J2EE zakázané techniky — vlastní thready
Jedním z pochybení, kterého se vývojáři enterprise/web aplikací v Jave dopouštějí je vytváření vlastních vláken za účelem asynchronní exekuce. Typicky se jedná o spouštění dlouhotrvajících procesů (generování reportů, odesílání velkých dat atd.) z prohlížeče a nebo o různé formy plánovačů např. pro čištění dočasných prostředků jako cache. Avšak využívání threadů k těmto účelům uvnitř aplikačních serverů je zakázáno a existují pro to rozumné důvody.
- Aplikační server je zodpovědný a musí garantovat správu zdrojů, proto je velice nepěkné vytvářet/alokovat nějaké zdroje bokem mimo jeho kontrolu. Odpadá tím například výhoda sdílení těchto zdrojů mezi aplikacemi.
- Není na škodu si připomenout, že EJB specifikace přímo vytváření threadů zakazuje. Některé aplikační servery, jako například IBM WebSphere, dokonce neumožňují práci (vyhození výjimky) s prostředky aplikačního serveru pokud není thread spravován přímo aplikačním serverem.
- Thready nejsou vhodné z hlediska clusteru např. failover, není je možné jednoduše restartovat a případný pád serveru nepřežijí. Samozřejmě netriviálním naprogramováním vlastního API, lze i toto vyřešit.
Každý aplikační server (JBoss, WebLogic, WebSphere) přitom nabízí oficiální prostředky pokryté specifikací a někdy i proprietární pro dosažení asynchronního zpracování. Samozřejmě v případě servletových kontejnerů jako Tomcat nebo Jetty je situace horší.
JMS
Základním prostředkem pro dosažení asynchronního zpracování je JMS (Java Message Service). Tuto službu musí mít každý J2EE server. JMS participuje v transakcích (odeslání/zpracování zprávy), je reliabilní — potvrzení přijmu, persistentní (přežije pád serveru), durable subsription a umožňuje posílání zpráv 1:1 a 1:M. Pokud je k dispozici JMS není co řešit.
Work Manager API
Work Manager API nabízí nepřímo vypůjčení threadů aplikačního serveru pro potřeby aplikace. Je sice pokryté JSR-237, ale není součástí J2EE specifikace, avšak jak aplikační server WebLogic taki WebSphere jej podporuje. Pokud tedy potřebujete k něčemu asynchronní exekuci a JMS nemůžete z nějakého důvodu použít, měl by být tento způsob preferovaný.
- The Work Manager API: Parallel Processing Within a J2EE Container
- The wise work manager for context-based scoping
- Timer and Work Manager for Application Servers
The Spring TaskExecutor abstraction
Spring TaskExecutor abstraction je abstraktní vrstva poskytovaná Spring frameworkem, která umožňuje asynchronní exekuci s možností nastavení vlastního thread poolu. Použití tohoto API bych doporučil z důvodů přenositelnosti, protože je možné snadno nastavit, aby se thready alokovaly pomocí Work Manager API (WebLogic, WebSphere) a nebo bokem (Tomcat, Jboss), když není možnost získat managed thready.
Výhoda tohoto řešení je v tom, že v prostředí, kde jsou thready spravované aplikačním serverem, lze tyto thready získat legálně. Tam kde tato podpora není, sice dochází k alokaci bokem, ale pokud se v dalších verzích produktu objeví, nebude problém změnou konfigurace přejít na její použití. Tento přístup může být preferovaný i pro deploymenty, kde není JMS k dispozici a nebo by jeho rozběhnutí složité.
Několik rada na závěr, pokud máte nutkání vytvářet nový thread:
- vytvářejte pouze počet threadů, které opravdu potřebujete někdy opravdu stačí jenom jeden
- pokud už takový thread máte, snažte se, aby nesahal na zdroje spravované aplikačním serverem
Související články
Související epizody CZ Podcastu
- #261 · Leadership
O vedení lidí a týmů.
- #3 · Java 6 SE, Vývoj webových aplikací
Dagi a Filemon o novinkách v Javě 6 a webových frameworcích.
- #1 · Vývojová prostředí v Javě
První díl CZ Podcastu se věnuje vývojovým prostředím pro Javu.