sobota 2. prosince 2006

Blog jako informační nástroj

Co je víc, podstata informace a nebo její využití?

Blog, a to ten odborný, je zcela jistě fenomén poslední doby. V mnoha firmách se blogování stalo jakousi součásti vnitrofiremní kultůry. Blog není jenom nástroj efektivního využívání informací. Naopak, může se pro firmu stát kompromitujícím prvkem v konkurenčním boji. Kde leží ona hranice? To jsou otázky, které si musí dříve nebo později uvědomit každý kdo se rozhodne sdílet informace.

Jak obecně řešíš sdílení znalostí s okolním světem? Přišel jsi na nějaké jednoduché pravidlo co zveřejnit a co ne? Některé z publikovaných článků by se daly považovat třeba z pohledu firmy za "nezveřejnitelné", protože leckdy by právě tento druh informací mohl způsobit konkurenční výhodu. Co myslíš - kde je ta hranice "tohle zveřejnit a tohle už ne"?

To nejjednodušší pravidlo je nezveřejňovat informace, které nejsou všeobecné známé. Jenže je ještě vůbec něco co není známe? Mnohem důležitější než informace sama je její aplikování a to by mělo zůstat vždy uvnitř firmy. Pokud napíšu článek o návrhu architektury aplikace, ale nezveřejním jakým způsobem to řeší daná firma, tak zveřejnění této informace nikoho nekompromituje.

Analogii je podobná jako v případě softwarový patent vs. autorské právo. Softwarový patent chrání informaci jako takovou beze zbytku. Oproti tomu autorské právo chrání to, jak je s danou informací naloženo, ne informaci samotnou. Z tohoto pohledu existuje i určitá exkluzivita informace. A potom je to čistě na svědomí a vědomí daného člověka.

Z pohledu globální komunity vývojáři drží spolu, ale v podstatě toto spojení nikdy nemůže být těsné, pokud jejich firmy mezi sebou soupeří (produktem, databází znalostí, interními procesy...)

To je podle mě omyl, určitě na úrovni softwarového průmyslu. To v čem spolu skutečně firmy soupeří je aplikování informací nikoliv jejich podstata, samozřejmě až na vzácné výjimky potvrzující toto pravidlo. Prostý fakt, že to takto funguje poskytuje sama praxe. Naopak, těch informací, které jsou ze své podstaty tajné je nepoměrně malé množství. Firmy se mezi sebou liší pouze v efektivnosti jejich využívání a aplikování.

Pouhé vlastnictví informace nezaručuje v globálním světě vůbec nic. Konkurenční výhoda je informaci umět aplikovat a to je know how, které by si firma měla chránit a nemělo by se zveřejňovat.

Kdybych měl vlastní firmu, tak bych naopak své zaměstnance podporoval v publikování vlastních názorů zakládajících se na veřejných informacích, bez ohledu na to jestli je firma využívá či nikoliv. Tím že veřejně vyjádřím svůj názor, mám možnost veřejné konfrontace. Díky konfrontaci mám zpětnou vazbu, kterou využiji k efektivnějšímu aplikování té samé informace, která byla na počátku.

Patří všechny informace všech zaměstnanců pouze a jenom jejich zaměstnavateli?

pátek 1. prosince 2006

JBoss cluster krok za krokem

JBoss logoChtěli by jste otestovat svojí webovou aplikaci v clusteru a nebo si prostě jenom takový cluster vyzkoušet. Pokud ano, můžete pokračovat čtením tohoto průvodce Jak vytvořit JBoss cluster krok za krokem. Nemělo by Vám to zabrat podle mých odhadů více jak patnáct minut.

Níže popsaným způsobem můžete cluster rozběhnout na jednom počítači. Není tedy potřeba více počítačů, samozřejmě pokud budete postupovat analogicky, tak je možný postup aplikovat i pro scénář kdy jsou jednotlivé uzly clusteru oddělené. Přesto má za určitých podmínek i cluster v rámci jednoho počítače opodstatnění. Například OS Windows limituje maximální množství paměti přidělené jednomu procesu, toto omezení se dá obejít právě díky rozběhnutí clusteru v rámci jednoho počítače.

Instalace JBosse

První věc, kterou musíme udělat je nainstalovat JBoss. Doporučuji stáhnout a použít instalátor. Při výběru instalační skupiny zvolte skupinu all tak budete mít JBoss s podporou clusteru. Všechny ostatní hodnoty necháme na defaultních hodnotách. Instalační složku JBosse budeme dále v textu označovat jako JBOSS_HOME.

Vytvoření uzlů clusteru

Po instalaci si vytvoříme cluster, který bude obsahovat dva nódy.

v adresáři JBOSS_HOME\server se nalézá adresář default. Ten dvakrát v tom samém adresáři zkopírujeme jednou pod jménem node1 a node2. Tím pádem budeme mít v JBOSS_HOME\server celkem tři adresáře default, node1 a node2.

V souborech JBOSS_HOME\server\node1\conf\jboss-service.xml a JBOSS_HOME\server\node2\conf\jboss-service.xml odkomentujeme následující beanu.

<mbean code="org.jboss.services.binding.ServiceBindingManager" name="jboss.system:service=ServiceBindingManager">

Navíc v tom samém konfiguračním souboru druhého uzlu změníme

<attribute name="ServerName">ports-01</attribute>

na

<attribute name="ServerName">ports-02</attribute>

Odkomentováním této beany jsme určili, že se nepoužijí defaultní porty, protože by nám dva JBoss server neběžely vedle sebe na jednom počítači. Místo těchto defaultních portů se použijí porty nadefinované v souboru ${jboss.home.url}/docs/examples/binding-manager/sample-bindings.xml. V tomto souboru jsou jsou pak pod klíčem ports-01 a ports-02 nadefinovány různé sady portů. Proto jsme v konfiguračním souboru druhého uzlu nastavili, aby použil jinou sadu.

Spuštěcí skripty

Nyní si vytvoříme spouštěcí skripty, které nám nastartují jeden či druhý node.

V adresáři JBOSS_HOME\bin vytvoříme soubor node1.bat a vložíme do něj run -g dagi -u 228.1.2.199 -c node1.

V adresáři JBOSS_HOME\bin vytvoříme soubor node2.bat a vložíme do něj run -g dagi -u 228.1.2.199 -c node2

Uživatelé Linux samozřejmě *.sh.

Parametr g resp. určuje jméno partition. Partition defiuje rodinu uzlů, které jsou sdruženy v daném clusteru. Proto naše dva uzly mají stejné jméno partition neboť patří do stejného clusteru. Parametr u definuje UDP multicast adresu, na které si budou jednotlivé nódy v clusteru dorozumívat.

Multicast adresu si můžete zvolit jako jsem to udělal já (228.1.2.199), ale musí být pro všechny uzly vašeho clusteru stejná. Každopádně, pokud jste v rámci sítě a někdo z kolegů si bude také zkoušet rozjet JBoss v clusteru a nastaví si stejné jméno partition a stejnou multicast adresu, tak se připojí do Vašeho clusteru. Z tohoto důvodu si zvolte jméno partition a multicast adresu s rozmyslem.

Pro vyzkoušení konfigurace clusteru nejdříve spustíme node1.bat a až nastartuje tak node2.bat. Můžeme to udělat i opačně protože na pořadí v případě JBoss clusteru nezáleží, všechny uzly jsou si rovny. Není zde žádný řídící uzel, který by se musel nahazovat. V logu uzlu, který jsem spustili by mělo být po startu druhého uzlu něco podobného následujícímu.

       
22:48:52,250 INFO  [dagi] New cluster view for partition dagi (id: 1, delta: 1)
: [10.0.0.3:1199, 10.0.0.3:1299]
22:48:52,250 INFO  [dagi] I am (10.0.0.3:1199) received membershipChanged event:
22:48:52,250 INFO  [dagi] Dead members: 0 ([])
22:48:52,250 INFO  [dagi] New Members : 1 ([10.0.0.3:1299])
22:48:52,250 INFO  [dagi] All Members : 2 ([10.0.0.3:1199, 10.0.0.3:1299])       
       
    

Nastavení loadvbalanceru

Takže máme již nastavený cluster, ale před ten musíme posadit load balancer, který bude rozdělovat jednotlivé příchozí HTTP požadavky na uzly našeho clusteru. Následuje obrázek z je originální JBoss dokumentace a ilustruje funkci load balanceru v případě, že jeden z uzlů clusteru odejde.

The load balancer architecture for clustering

Protože JBoss používá jako HTTP server Tomcat, který podporuje mod_jk je možné jako load balancer použí HTTP server Apache.

Takže pusťmě se do toho!

Instalace

Doporučuji Vám sthánout kompatibilní verze mod_jk a Apache. Ja jsem stáhnul mod_jk-apache-2.2.3 a instalátor Apache 2.2.3. Při instalaci samotného Apache serveru není potřeba nic měnit, můžete použí defaultní hodnoty. Jenom si dejte pozor, že nemáte obsazený defaultní port 80 pro HTTP komunikaci např. jiným serverem (IIS) či jiným programem. Instalační adresář Apache je odkazován jako APACHE_HOME.

Po instalaci nakopírujte stahnutý mod_jk-apache-X.Y.Z.so do adresáře APACHE_HOME\modules a přejmenujte na mod_jk.so.

Apache konfigurace

Přidejte následující řádek Include conf/mod-jk.conf na konec souboru APACHE_HOME\conf\httpd.conf.

Vytvořte soubor APACHE_HOME\conf\mod-jk.conf a vložte do něj následující obsah.

     
# Load mod_jk module
# Specify the filename of the mod_jk lib
LoadModule jk_module modules/mod_jk.so
 
# Where to find workers.properties
JkWorkersFile conf/workers.properties

# Where to put jk logs
JkLogFile logs/mod_jk.log
 
# Set the jk log level [debug/error/info]
JkLogLevel info 
 
# Select the log format
JkLogStampFormat  "[%a %b %d %H:%M:%S %Y]"
 
# JkOptions indicates to send SSK KEY SIZE
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
 
# JkRequestLogFormat
JkRequestLogFormat "%w %V %T"
               
# Mount your applications
JkMount /application/* loadbalancer
 
# You can use external file for mount points.
# It will be checked for updates each 60 seconds.
# The format of the file is: /url=worker
# /examples/*=loadbalancer
JkMountFile conf/uriworkermap.properties               

# Add shared memory.
# This directive is present with 1.2.10 and
# later versions of mod_jk, and is needed for
# for load balancing to work properly
JkShmFile logs/jk.shm 
              
# Add jkstatus for managing runtime data
<Location /jkstatus/>
    JkMount status
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
</Location>         
     
    

Vytvořte soubor APACHE_HOME\conf\uriworkermap.properties a vložte do něj následující obsah.

    
# Simple worker configuration file

# Mount the Servlet context to the ajp13 worker
/jmx-console=loadbalancer
/jmx-console/*=loadbalancer
/web-console=loadbalancer
/web-console/*=loadbalancer

/test/*=loadbalancer
/test=loadbalancer    
    
    

Tím je řečeno, které sub cesty budou směrovány load balancerem. Jinýmy slovy jakýkoliv HTTP požadavek na http://hostname/jmx-console nebo http://hostname/web-console a nebo http://hostname/test doručí na jeden z uzlů v našem clusteru. Aplikace jmx-console a web-console jsou v JBossu standardně. Pro naše budoucí testovací účely jsme připravil ješte mapování aplikace test. Pokud si to budete chtít vyzkoušet nějakou aplikaci, pak stačí aby byla v JBossu deploynutá v kontextu test případně si samozřejmě můžete namapovat vlastní existující aplikaci. Stačí pouze uvést její kontext.

Dále (už se blížíme do finále) je potřeba vytvořit soubor APACHE_HOME\conf\workers.properties a do něj vložit následující obsah.


# Define list of workers that will be used
# for mapping requests
worker.list=loadbalancer,status

# Define Node1
# modify the host as your host IP or DNS name.
worker.node1.port=8109
worker.node1.host=localhost 
worker.node1.type=ajp13
worker.node1.lbfactor=1
worker.node1.cachesize=10

# Define Node2
# modify the host as your host IP or DNS name.
worker.node2.port=8209
worker.node2.host=localhost
worker.node2.type=ajp13
worker.node2.lbfactor=1
worker.node2.cachesize=10

# Load-balancing behaviour
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=node1,node2
worker.loadbalancer.sticky_session=1
#worker.list=loadbalancer

# Status worker for managing load balancer
worker.status.type=status    
    
    

Pozn: všiměte si hodnoty worker.node1.port a worker.node2.port. To jsou porty, na kterých poslouchá JK konektor JBosse resp. Tomcatu.

Konfigurace Tomcatu uvnitř JBosse

Poslední věc, kterou musíme udělat je nastavení Tomcatu a jeho Mod_JK.

V souboru JBOSS_HOME\server\node1\deploy\jbossweb-tomcat55.sar\server.xml přidejte do elementu Engine atribut jvmRoute="node1". Ten potom vypadá následovně

   <Engine name="jboss.web" defaultHost="localhost" jvmRoute="node1">
   

V souboru JBOSS_HOME\server\node2\deploy\jbossweb-tomcat55.sar\server.xml přidejte do elementu Engine atribut jvmRoute="node2". Ten potom vypadá následovně

   <Engine name="jboss.web" defaultHost="localhost" jvmRoute="node2">
   

V souboru JBOSS_HOME/server/node1/deploy/jbossweb-tomcat55.sar/META-INF/jboss-service.xml a JBOSS_HOME/server/node2/deploy/jbossweb-tomcat55.sar/META-INF/jboss-service.xml změňte obsah elementu attribute s atributem name a hodnotou UseJK na true.

   
<attribute name="UseJK">true</attribute>

A to je vše, nyní máme cluster připravený včetně loadbalanceru.

V případě nejakých nejasností doporučuji konzultovat postup s JBoss originální dokumentací. Konkrétně sekce 16.5. HTTP Services v rámci kapitoly 16. clustering.

Zkouška clusteru

  • nastartujte Apache
  • nahoďte uzel 1
  • nahoďte uzel 2
  • otevřete prohlížeč a zadejte adresu http://localhost/web-console/. Pokud Vám Apache poslouchá na jiném portě než 80, tak jej musíte zadat. Webová konzole je defaultni chráněná jménem a heslem, které jste zadali v jednom z instalačních kroků JBosse.
  • Na stránce webové konzole, je v pravém rámu informace Running config: 'XXX'. Pokud několikrát za sebou zadáte adresu http://localhost/web-console/ a mezi každým požadavkem si smažete cookies a nebo použijete jinou instanci prohlížeče tak by jste se měli čas od času dostat na jiný uzel. Tedy bude se měnit nápis Running config: 'Node1' za Running config: 'Node2' a naopak.

Pokud se Vám za žádných okolností nepovede, že prohlížeč nepujde alespoň někdy (po vymazání cookies či puštěním jiné instance prohlížeče) na jiný uzel, pak je něco špatně. V opačném případě gratuluji, máte úspěšně nastavený a fungující JBoss cluster. O tom proč jsme mazali cookies aneb sticky session a jak udělat aplikaci, která bude automaticky replikovat HttpSession zase příště.

Tenhle článek by nikdy nevzniknul nebýt Gala Mardera VP R&D z firmy InterBit.

Thank you very much, you are the real Java champion!

neděle 26. listopadu 2006

Java trpí nedostatkem hostingů

Ze všech stran se na nás valí připravované novinky v JDK6 a JDK7, které by měly zvýšit efektivitu, zkvalitnit a zjednodušit vývoj v Jave. Jenže problém Javy leží trochu někde jinde než ve vývojové fázi. Problematickou fází, alespoň pro určitou část vývojářů, je hosting Java aplikací. Jedním z mýtů o Jave je, že není tak efektivní jako PHP. K šíření tohoto nesmyslu nezanedbatelnou měrou pomáhá fakt, že není jednoduše možné hostovat webové aplikace v Jave takřka kdekoliv jako v případě PHP.

Jenom v České republice existuje velké množství freehostingu pro PHP aplikace a ještě větší množství placených hostingu a ve světě je tomu stejně. Oproti tomu freehostingy Javy by se v celosvětovém měřítku dali spočítat na prstech jedné ruky. V placeném hostingu je sice situace lepší, ale to k popularizace Javy pro web samozřejmě nestačí.

K čemu je Jave skvělá variabilita middleware produktů, když to základní, tedy aplikaci někde hostovat (pokud možno zdarma) chybí. Samozřejmě je pro vývojáře mnohem lepší, když může svou aplikaci nasadit takřka kdekoliv, než přemýšlet kde by to vlastně vůbec šlo a za kolik. V PHP i v Jave si doma uplácáte na koleně aplikaci za pár dní, jenže narozdíl od té v PHP můžete tu v Jave strčit do šuplíku pokud si nezaplatíte hosting a nebo si nerozjedete vlastni server.

Jenže ono se to lehce řekne udělat hosting Java aplikací, ale hůře se to provádí. Java jako platforma pro web je v současném modelu, alespoň podle mého názoru, velice obtížně hostovatelná. Největší problém je izolace jednotlivých web aplikací uvnitř JVM. Ač je snadné zamezit naschválnému kódu alá System.exit(0) díky SecurityManageru, zůstává několik dost závažných problémů.

sdílený paměťový prostor
paměťová náročnost či případně memory leak jedné webové aplikace složí všechny zbylé uvnitř VM. Paměťový prostor VM je shora striktně omezen maximální hodnotou, která je zadaná při startu VM a která nemůže být při běhu přesáhnutá.
velká paměťová náročnost
díky paměťovému modelu a jeho správě Garbage Collectorem (uklízeč, sběrač neplatných objektů) je Java server mnohem více paměťově náročnější než klický http server. S každým HTTP požadavkem vzniká velké množství nových objektů, kterou jsou po jeho skončení k ničemu a čekají až je GC odstraní. To samo o sobě není problém, ale GC musí být velice citlivě nastaven tak, aby nepracoval na hranici zaplnění celého heapu a nedocházelo k jeho častému volání, které by vyústilo ve značné zpomalení běhu serveru.

Od verze 1.4 je možné významně ovlivnit chování GC. Paměťová náročnost není z hlediska správy jedné aplikace, kterou máme pevně v ruce problém. Jenže v případě veřejného serveru máme množství paralelně bežících aplikací uvnitř jedné VM, které se mohou velice nepříjemně ovlivňovat.
DOS náchylnost
Je možné snadno dosáhnout DOS (Denial of Service) útoku relativně nezávadným kódem. Dva příklady. Prvním z nich je nekonečný cyklus způsobí plné vytížení procesoru po dobu do vypršení timeoutu HTTP požadavku. Druhý příklad představuje vytvoření nového HTTP požadavku na sebe zevnitř bežícího vlákna zpracovávajícího HTTP požadavek. To vede k vyčerpání vnitřních vláken určených k obsloužení požadavků. Výsledkem je, že server je schopen akceptovat HTTP požadavky, ale není schopen je vnitřně obsloužit - vzniká deadlock. Vytváření nových vláken je limitované zdroji operačního systému např. na OS Linux je každé Java vlákno mapováno jedna ku jedné na vlákno operačního systému.

Pozn: Některé aplikační servery nabízejí možnost nastavení dedikovaných thread poolu (jak se to řekne česky?) per aplikace.
nešetrnost hot deploymentu
Pokud dojde ke změně JSP aplikační server může snadno nové JSP zkompilovat a použít. V případě tříd to tak snadno nejde. Za nahrávání tříd je v Jave zodpovědný classloader, ale ten neumožňuje prostou výměnu staré třídy za novou. Naštěstí každá webová aplikace má uvnitř serveru vlastní classloader. Pokud je detekovaná (sledováním souborového systému) nová verze některé třídy, zahodí se celý classloader dané aplikace a aplikace resp. její třídy se nahrají znovu novým classloaderem - tomu se říká hot deployment.

Nahrávání celé aplikace při změně každé třídy je v produkčním prostředí systémově drahé. To znamená, že infrastruktura hostingu musí počítat vždy s dvojicí serverů - produkční a testovací. Na testovacím, kde je hot deployment zapnutý, se aplikace vyladí a poté se propaguje na produkční server. To je mnohem náročnější na vývoj než prosté nakopírování nového PHP souboru na server.

Pozn: Při hot deploymentu dochází například na serveru Tomcat k nepříjemnému memory leaku, který vzniká díky tomu, že GC nemůže uvolnit speciální oblast heapu, která slouží k definici tříd.

Ano i tyto problémy jako každé lze nějak řešit nebo omezit jejich dopad. Otázka je proč Sunu tato situace nevadí. Kdyby se totiž podařilo tyto problémy vyřešit, rozšířenost Javy by se nepochybně mnohonásobně zvýšila. Dokonce existuje JSR 121 (Isolation API, Resource management API viz A Resource Management Interface for the Java Platform(PDF)), které bylo úspěšně použito v prototypu takzvané MVN (Multitasking Virtual Machine) a tyto problémy může významnou měrou pomoci redukovat.

Ještě více je zarážející, že koncept MVN a nebo jeho aspekty Sun aplikoval pro oblast mobilních zařízení kde bylo nutné brát zřetel na omezené zdroje. Korunu všemu dává Sun tím, že pro vlastní stránky používá PHP. Ať už je to z jakéhokoliv důvodu, člověka hned napadne že nepojídají jídlo, které sami produkují.

Ač to bude možná znít zvláštně, tak právě nyní je největší možnost s tím něco dělat. Díky otevření Javy jako open source je nyní možné prosadit koncept JSR 121 mnohem snáze. Přenositelná implementace MVM a aplikační server využívající isolation API a resource management by mohla znamenat zlom. V této souvislosti je velice zajímavé, že ať už BEA Weblogic či IBM WebSphere měli vlastní implementace JVM a nešáhli po něčem podobném.

Kdybych si měl vybrat mezi tím, jestli tu bude široce dostupný Java web hosting díky forku JVM na MVN a nebo ideovou čistotou JVM, tak volím raději potenciálně nebezpečnější fork...