Usare i Virtual Hosts di TomCat |
Home Page | Commenti | Articoli | Faq | Documenti | Ricerca | Archivio | Storie dalla Sala Macchine | Contribuire | Imposta lingua:en it | Login/Register
Di solito, quando si hanno piu' web applications in TomCat ("contesti"), queste sono divise in diverse directory o diverse istanze di TomCat. L'utilizzo di molteplici istanze consente di avviare/riavviare/fermare una sola applicazione senza che le altre ne risentano, ma significa anche l'avere molteplici processi in funzione con consumo di memoria e tempo di processore.
Dividere le applicazioni in diversi contesti va' benissimo, ma qualche volta non si vuole dover aggiungere il pezzo "/context" all'URL per richiamare una specifica applicazione. In questi casi cio' che si fa' solitamente e' definire un Virtual Host in Apache ed "attaccare" la docroot del vhost direttamente al contesto di TomCat (con o senza il mod_jk).
C'e' pero' una alternativa: usare direttamente i Virtual Hosts in TomCat.
Cosi' come per Apache, vi sono due modi di definire ed usare i Virtual Hosts in TomCat: basandosi su diversi indirizzi IP (e/o porte) o basandosi sul nome dell'host. Nel primo caso TomCat sara' in ascolto su diversi indirizzi IP ed a seconda dell'indirizzo verra' "servito" un diverso contesto, nel secondo caso la selezione verra' fatta mediante il nome host contenuto nella richiesta HTTP.
In entrambi i casi occorre definirli nel file di configurazione server.xml.
Per avere TomCat in ascolto su diversi indirizzi IP (o porte), occorre definire diversi "services" nel server.xml. Se prendiamo un server.xml di default e rimuoviamo tutti i commenti e la roba di cui si puo' fare a meno otteniamo piu' o meno la seguente definizione "minima":
<?xml version='1.0' encoding='utf-8'?> <Server port="8007" shutdown="SHUTDOWN"> ...a lot of stuff... <Service name="Catalina"> <Connector port="8080" address="127.0.0.1" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8009" address="127.0.0.1" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> <Host name="localhost" appBase="webapps" unpackWARs="false" autoDeploy="false" xmlValidation="false" xmlNamespaceAware="false"> </Host> </Engine> </Service> </Server>
Il trucco e' il blocco <Service > ... </Service>. Ogni "blocco" definisce un "servizio" che puo' essere in ascolto su piu' IP/porte e gestire diversi "host". Ogni host/servizio puo' avere una diversa "appBase" e diversi "contesti". Notare che, di solito, il parametro "address" non e' specificato ed i servizi ascoltano su tutti gli ip disponibili sulla porta specificata.
Per aggiungere un altro servizio in ascolto su una porta/ip diversa, dobbiamo solo fare un cut & paste del blocco e cambiare gli ip/porte ed il nome del servizio. Dovremmo anche ovviamente definire un diverso appBase per il nostro nuovo servizio.
<Service name="Catalina"> ..just like above... </Service> <Service name="Catalina2"> <Connector port="8081" address="127.0.0.1" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8019" address="127.0.0.1" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> <Host name="localhost" appBase="wathever" unpackWARs="false" autoDeploy="false" xmlValidation="false" xmlNamespaceAware="false"> </Host> </Engine> </Service>
In questo caso abbiamo un servizio in ascolto sulle porte 8081/8019 (per http/ajp) e con una appBase di "wathever" (quella e' la directory in cui sono le varie web applications).
In alternativa ai vhost basati su IP vi sono quelli basati su diversi Nomi host. Per definire questo tipo di vhost occorre definire piu' blocchi Hosts all'interno dello stesso servizio. Prendendo l'esempio precedente come base:
<Service name="Catalina"> <Connector port="8080" address="127.0.0.1" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8009" address="127.0.0.1" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> <Host name="localhost" appBase="webapps" unpackWARs="false" autoDeploy="false" xmlValidation="false" xmlNamespaceAware="false"> </Host> <Host name="hostname_01" appBase="wathever" unpackWARs="false" autoDeploy="false" xmlValidation="false" xmlNamespaceAware="false"> </Host> </Engine> <Service>
In questo caso abbiamo definito due virtual host, uno che risponde a "localhost" ed e' anche il "default" per il servizio ( parametro defaultHost dell'Engine ) ed uno chiamato "hostname_01" con una diversa appbase. Ovviamente il nome deve essere il FQDN dell'host. Notare che almeno uno degli Host definiti deve corrispondere al "defaultHost" definito per l'Engine.
Il 'defaultHost' viene usato se una richiesta che non corrisponde a nessun Vhost viene ricevuta.
Se l'host deve anche rispondere a diversi nomi (capita spesso con e senza la 'www.'), e' possibile definire piu' "alias" per l'host usando dei blocchi <Alias>...</Alias> all'interno dell'Host stesso:
<Host name="www.somedomain.com" appBase="wathever" unpackWARs="false" autoDeploy="false" xmlValidation="false" xmlNamespaceAware="false"> <Alias>somedomain.com</Alias> </Host>
In ogni caso, se vogliamo che la "root" del vhost sia associata ad uno specifico contesto (applicazione), dovremo definire un Context per l'host, qualche cosa tipo:
<Host... <Context path="" docBase="examples"/> </Host>
In questo modo quando l'host viene richiesto (come IP o come Nome), l'applicazione identificata viene 'servita' al client.
Il maggior problema di questo sistema e' che per ogni nuovo Host definito occorre modificare il file di configurazione generale di tomcat e riavviare l'istanza. Purtroppo TomCat non supporta, come Apache, la possibilita' di "includere" molteplici file di configurazione usando caratteri jolly (Include *.conf), quindi non e' possibile semplicemente aggiungere un file di configurazione in una directory e dare un restart al server.
Una possibile soluzione al problema potrebbe essere il "costruire" il file di configurazione facendo il "merge" di diversi files di configurazione mediante uno script prima di avviare TomCat, utilizzando una sorta di "wrapper" attorno al normale script di star/stop. Un ovvio svantaggio di questo approccio pero' e' che l'avvio di TomCat usando il normale script potrebbe avere risultati inattesi (non funziona un tubo e nessuno capisce perche').
I commenti sono aggiunti quando e soprattutto se ho il tempo di guardarli e dopo aver eliminato le cagate, spam, tentativi di phishing et similia. Quindi non trattenete il respiro.
Di Virtual host postato il 11/02/2011 14:32
Ciao Davide, intanto grazie per la spiegazione, ma mi sono arenato da qualche parte perché tutti i vhost mi rimandano su quello di default. Penso di non aver capito il valore della variabile appBase ed i parametri da impostare alla Context. Fisicamente su disco cosa deve risultare? Io ho fatto due deploy di due applicazioni dal formato WAR. Cosa dovrei mettere nei parametri appena detti?
Grazie
Giorgio
-- Virtual host
Davide Bianchi, lavora come Unix/Linux System Administrator presso una societa' di Hosting in Olanda.
Il presente sito e' frutto del sudore della mia fronte (e delle mie dita), se siete interessati a ripubblicare uno degli articoli, documenti o qualunque altra cosa presente in questo sito per cortesia datemene comunicazione (o all'autore dell'articolo se non sono io), cosi' il giorno che faccio delle aggiunte potro' avvisarvi e magari mandarvi il testo aggiornato.
Questo sito era composto con VIM, ora e' composto con VIM ed il famosissimo CMS FdT.
Questo sito non e' ottimizzato per la visione con nessun browser particolare, ne' richiede l'uso di font particolari o risoluzioni speciali. Siete liberi di vederlo come vi pare e piace, o come disse qualcuno: "Finalmente uno dei POCHI siti che ancora funzionano con IE5 dentro Windows 3.1".