Apache 2.0 & Tomcat 4.1

21. 3. 2003
Doba čtení: 7 minut

Sdílet

Hybridní instalaci WWW serveru Apache a JSP serveru Tomcat umožňuje modul mod_jk. Apache servíruje statické dokumenty a JSP stránky a servlety předává Tomcatu. Následující článek popisuje instalaci a v samotném závěru najdete ukázku load balancing konfigurace mezi dvěma Tomcaty.

Krok 1: Apache 2.0

V současné době máme na výběr z dvou www serverů Apache, je to verze 1.X a 2.X. Nová verze, jak jistě víte obsahuje mnoho novinek, zejména kompletní přepsání výkonného jádra, což může vést ke zlepšení výkonu. V mém případě se budeme věnovat novému Apache 2.0. Ať zvolíte jakkoliv, stáhněte si zdrojové kódy, zkompilujte je a nainstalujte (v mém případě to bude /opt/apache). Rád bych poznamenal, že by následující návod měl fungovat jak s verzemi 1.X, tak i v případě, pokud použijete binární distribuci.

Jen krátce ke kompilaci, protože tomuto tématu bylo na rootu věnováno hodně. U nového Apache 2.0 si můžete vybrat jádro serveru (MPM). Pro Linux máme k dispozici například standardní modul prefork, který je instalován implicitně, worker, jenž používá více procesů, ale každý má více vláken, nebo experimentální leader. Pokud bychom tedy chtěli použít vícevláknový modul, museli bychom napsat:

/configure –prefix=/opt/apache –with-mpm=worker –enable-mods-shared=all –enable-modules=„defla­te ssl“

Tato konfigurace nejen, že místo prefork verze používá vícevláknovou, zároveň všechny moduly zkompiluje sdíleně a navíc přidává dva užitečné moduly SSL a deflate, které nejsou zahrnuty v all kompilaci. Modul worker funguje tak, že Apache při startu aktivuje několik procesů (workers), přičemž každý proces má pevný počet vláken. Pokud si to zatížení vyžádá a konfigurace to dovoluje, může být spuštěn další proces. Je to z toho důvodu, že spuštění vlákna něco stojí. Každý proces navíc implementuje sdružování (thread pooling), které bylo převzato ze samostatného modulu threadpool. Následuje ukázková konfigurace:

<IfModule worker.c>
 StartServers 4
 MaxClients 200
 MinSpareThreads 25
 MaxSpareThreads 100
 ThreadsPerChild 25
 ServerLimit 10
</IfModule>

Krok 2: JDK (JRE) 1.4

V následujících krocích budeme instalovat javovské programy. Pokud nechcete provádět kompilaci nebo ruční instalaci, kterou v tomto návodu použiji, můžete využít služeb serveru www.jpackage.org, na kterém se nalézají RPM balíčky mnoha programů napsaných v Javě. Tyto RPM balíčky obvykle instalují do  /usr.

Doporučuji stáhnout a nainstalovat (v mém případě /opt/java) tu od Sunu, protože obsahuje vysoce výkonné jádtro HotSpot-server, které Tomcat umí použít (resp. aktivovat jej přepínačem – pokud jej najde). Pokud splníte následující podmínky: a) nebudete JSP vyvíjet, b) do Tomcatu dodáte pouzepředkompi­lované JSP stránky, bude vám stačit JRE. Rád bych zdůraznil, že pokud distribuujete své JSP stránky nepředkompilované (což je běžná praxe), budete stejně potřebovat JDK, protože JSP kompilátor Jasper vyžaduje javac. Doporučuji tedy raději stáhnout JDK, protože bez dokumentace to není zas tak moc velké.

Krok 3: Ant 1.5

Pro sestavení propojovacího modulu JK2 budeme potřebovat Ant. Stáhněte si jej ze stránek Jakarta (aktuální verze 1.5), přičemž bohatě postačí binární distribuce (Ant se bez Anta špatně kompiluje). Nainstalujte jej (u mě je to /opt/ant) a nastavte ANT_HOME.

Krok 4: Apache Tomcat 4.1

Instalace JSP kontejneru je opravdu jednoduchá. Binárku rozbalíme do adresáře (např. /opt/tomcat) a nastavíme TOMCAT_HOME. Po spuštění můžeme otestovat, zda je kocour na svém místě. Přesvědčíme se o tom webovým prohlížečem nebo telnetem připojením na adresu localhost:8080, protože právě tam by měl číhat HTTP konektor Coyote.

Krok 5: Kompilace modulu JK

Nejprve se musíte rozhodnout, kterou verzi hodláte použít. Verze JK 1.x je poměrně stabilní a funguje se servery Apache 1 i 2, IIS a iPlanet, kdežto verze JK 2.0, která je ušitá na míru serveru Apache 2.0 a podporuje navíc unix-socket komunikaci a v budoucnu i NIO, je ve fázi testování a její plné nasazení se nedoporučuje. Tak jako tak, stáhněte zdrojový kód Tomcata, kde se nalézají obě verze. Alternativně můžete stáhnout pouze zdrojový kód modulu JK případně předkompilovanou verzi a to přímo ze stránek mod_jk, avšak pro kompilaci pak musíte opravit cesty v sestavovacím skriptu build.xml tak, aby JK nalezl knihovnu Coyote.

My se budeme věnovat verzi JK1, protože experimentální „dvojku“ se mi zatím nepodařilo přesvědčit, aby s mým Tomcatem pracovala. Vybalme tedy zdrojový kód Tomcatu a přejděme do adresáře jtc-src. Postupně projdeme následující adresáře, ve kterých musíme zeditovat soubory build.properties(příklady jsou v build.properties.sample). Tyto adresáře jsou: coyote, jk a util. Sice se jedná obvykle o nastavování cest, ovšem pokud se chcete dalšímu nastavování vyhnout, doporučuji všechny důležité hodnoty zkopírovat do vašeho domovského adresáře ( ~/build.properties), kde je Ant pro příště bez problému najde.

Po správném nastavení sestavovacích parametrů přejdeme zpět do adresáře jtc-src a spustíme ant. Sestaví se nám oba JK a JK2 moduly pro Tomcat (tedy javovské knihovny). Tyto knihovny můžeme překopírovat k Tomcatu, pokud tam zatím nebyly (u binární distribuce je tam ale již máte). V následujícím kroku musíme sestavit moduly pro Apache. Použijeme proto příkaz ant native v adresáři jtc-src/jk. Ant zkompiluje opět obě verze.

Setkal jsem se s dvěma problémy, což vám může ulehčit práci. Za prvé, může se stát (např. u JDK 1.4.0_03 od Sunu), že nebude nelezen soubor JDK_HOME/include/jni_md.h. On se totiž nalézá v podadresáři linux, proto tam na něj vytvořte symbolický link. Za druhé, vzhledem k tomu, že jsou ještě práce na APR knihovnách značné, po sestavení Apache se někdy nevytvoří link libapr.a -> libapr-verze.a. Proto také linkování nativních knihoven pro Apache může na tomto ztroskotat. Pomůžete si opět vytvořením symbolického linku.

Nyní můžeme přejít do adresáře build. Najdeme tam ukázkové konfigurační soubory, knihovny pro Tomcat (adresář lib) a nativní knihovny pro Apache (adresáře jk a jk2). Sestavené so moduly z adresáře JK2 tedy nakopírujme do  APACHE_HOME/modules.

Krok 6: Konfigurace

Nyní můžeme přistoupit k vlastní konfiguraci. Tomcat lze nastavit tak, že bude generovat ze svých konfiguračních souborů konfiguraci pro Apache. Ta se potom pouze vloží do httpd.conf. Důležité je to, že Tomcat musí být nastartován před Apachem. Někdy se vyplatí po startu Tomcatu počkat pár vteřin (asi 20), protože start Tomcatu je asynchronní a Apache může ve startování Tomcata „předběhnout“ a konfigurace může být zastaralá. Nutno poznamenat, že pokud Apache a Tomcat nejsou na stejném stroji, musíte konfigurovat ručně.

Nastavme tedy Tomcata pro generování auto-konfigurace. Do všech značek Server a Host v souboru server.xml je nutno přidat nový Listener takto:

Tabulka č. 396
<Server port="8005" shutdown="SHUTDOWN" debug="0">
...
 <Listener
   className="org.apache.ajp.tomcat4.config.ApacheConfig"
   modJk="/opt/apache/modules/mod_jk.so" /> 
...

  <Host name="localhost" debug="0" appBase="webapps" 
     unpackWARs="true" autoDeploy="true">

   <Listener
      className="org.apache.ajp.tomcat4.config.ApacheConfig" 
      append="true" />
  </Host>

... atd pro všechny Hosty ...

</Server>
Nastavení automatického generování konfigurace pro Apache

Nyní stačí do httpd.conf přidat následující řádek (předpokládám umístění Apache v adresáři  /opt):

Include /opt/tomcat/conf/auto/mod_jk.conf 

Tato direktiva by měla být použita před načtením ostatních modulů. Posledním krokem je vlastní konfigurace modulu JK. Ta je také ze všeho nejzajímavější, protože máme na výběr z několika možností komunikace mezi oběma servery: TCP protokol AJP 1.2, AJP 1.3 (který je novější), JNI a LoadBalancer. Konfigurace se provádí v souboru workers.properties. První dva způsoby jsou nejpoužívanější. Umožňují komunikaci mezi Apachem a Tomcatem po TCP protokolu. Novější verze 1.3 je o něco lepší, umožňuje SSL, ponechávat spojení (keep-alive) a jiné drobnůstky. Proto byste měli zvolit právě tento konektor.

Máte-li chuť experimentovat, můžete zkusit nakonfigurovat JNI modul. Při tomto způsobu probíhá komunikace přímo přes JNI (Java Native Interface), což bude pravděpodobně nejrychlejší metoda ze všech čtyř. Nutno poznamenat, že je použitelná jen tehdy, pokud jsou oba servery na stejném stroji. Já jsem JNI nezkoušel, protože tento modul není příliš dobře zdokumentován a ukázkové příklady jsou zastaralé (platné pro Tomcat 3.X).

bitcoin_skoleni

Ze všeho nejzajímavější se jeví konektor LoadBalancer. Je to věc, která umí delegovat dotazy na jiné konektory (AJP 1.2, 1.3 nebo JNI). Nejrozumnější je zde použít AJP 1.3, a to samozřejmě na několik různých počítačů. LoadBalancer má naimplementován jednoduchý round-robin algoritmus přidělování konektorů. Jinými slovy každý chvilku tahá pilku. LoadBalancer si pamatuje sezení (client sesions), a pokud již konkrétního uživatele přidělil jednomu serveru, přidělí mu ho opakovaně. Následuje malá ukázka konfigurace LoadBalanceru na dva stroje:

Tabulka č. 397
<!-- TOMCAT_HOME/conf/server.xml -->

<Server port="8005" shutdown="SHUTDOWN" debug="0">
...
 <Listener
   className="org.apache.ajp.tomcat4.config.ApacheConfig"
   modJk="/opt/apache/modules/mod_jk.so" />   
...

  <Host name="localhost" debug="0" appBase="webapps" 
     unpackWARs="true" autoDeploy="true">

   <Listener
      className="org.apache.ajp.tomcat4.config.ApacheConfig"
      jkWorker="loadbalancer"
      append="true" />
  </Host>

... atd pro všechny Hosty ...

</Server>

#
# workers.properties 
#

worker.list=tomcat1, tomcat2, loadbalancer

worker.tomcat1.port=8009
worker.tomcat1.host=alpha
worker.tomcat1.type=ajp13
worker.tomcat1.lbfactor=100

worker.tomcat2.port=8009
worker.tomcat2.host=beta
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor=100

worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=tomcat1, tomcat2
Jednoduchý load balancing

Závěr

Hybridní konfigurace serverů Apache a Tomcat se nasazuje tehdy, kdy je na aplikaci kladeno veliké zatížení jak na statické, tak i na dynamické dokumenty. Apache 2.0 je velmi rychlý a flexibilní webový server a v kombinaci s kontejnerem Tomcat nabízí stabilní platformu pro webovou Javu. Pokud však aplikace neobsahuje příliš mnoho dotazů na neměnné HTML stránky a obrázky, doporučuji přemýšlet o čistě javovské konfiguraci (tzn. pouze server Tomcat s konektorem Coyote). Na tomto poli také řádí ještě jeden, velice rychlý kontejner, a to server Jetty. O tom ale snad zase příště u dalšího článku věnovaného Javě na Linuxu.