**Cette page a été importée automatiquement de notre ancien wiki mais n'a pas encore été révisée.** ## Howto Tomcat ### Installation Sous Debian Lenny, Tomcat 6 n'est pas présent. Nous utilisons donc un backport de la version présente dans Squeeze. Vous pouvez la retrouver dans le repository Evolix dans ~~~ # aptitude install sun-java6-jdk tomcat6 ~~~ La configuration de la JVM dans le fichier _/etc/default/tomcat6_ : ~~~ # Rare sont les cas ou l'on peut activer le Java security manager TOMCAT6_SECURITY=no # Reglages memoire de base (a adapter selon votre quantite de RAM, dans l'exemple on a une seule instance et 4 Go de RAM) JAVA_OPTS="${JAVA_OPTS} -Xms1g -Xmx2g -XX:NewSize=512m -XX:MaxPermSize=256m -Xss256k" # Reglages du garbage collector JAVA_OPTS="${JAVA_OPTS} -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:CMSInitiatingOccupancyFraction=80" # Compression des adresses 64bits sur 32bits pour gagner en memoire libre JAVA_OPTS="${JAVA_OPTS} -XX:+UseCompressedOops" # file limits pour eviter les "too many open files" ulimit -n 8192 ~~~ La configuration de Tomcat peut être dispersée dans de nombreux fichiers et utilise des variables à bien avoir en tête : ~~~ CATALINA_BASE : ${catalina.base} = /var/lib/tomcat6 CATALINA_HOME : ${catalina.home} = /usr/share/tomcat6 ~~~ En ce qui concerne le chargement des classes (Class Loader), un résumé pragmatique pourrait être : ~~~ /usr/share/tomcat6/lib/ : classes communes à toutes les webapps WebappX/WEB-INF/lib/ : classes spécifiques à la webapp WebappX ~~~ Pour désactiver le déploiement automatique (à chaud), on modifie le fichier /etc/tomcat6/server.xml : ~~~ ~~~ Pour installer le driver JDBC pour MySQL : ~~~ # aptitude install libmysql-java # cd /usr/share/tomcat6/lib/ # ln -s ../../java/mysql-connector-java.jar mysql.jar ~~~ Pour installer le driver JDBC pour PostgreSQL : ~~~ # aptitude install libpg-java # cd /usr/share/tomcat6/lib/ # ln -s ../../java/mysql-connector-java.jar mysql.jar ~~~ ## Instances Il est possible d'avoir plusieurs instances de Tomcat. Cela permet de faire tourner plusieurs processus Tomcat de faon complétement indépendantes, avec leurs propres réglages et en permettant des arrêts/redémarrages d'une instance sans impacter les autres. Sous Debian, il existe notamment un script nommé tomcat6-instance-create qui se charge de copier les répertoires utiles (conf, logs, webapps, etc.) tout en mutualisant les binaires. Cela évite de dupliquer les binaires communs et permet d’optimiser les mises à jour. ~~~ # ls /src/tomcat6/*/ /src/tomcat6/app1: bin conf logs pid temp webapps work /src/tomcat6/app2: bin conf logs pid temp webapps work ~~~ Voici comment créer une nouvelle instance : ~~~ # tomcat6-instance-create /srv/tomcat6/app3 # useradd -d /srv/tomcat6/app3 app3 # mkdir /srv/tomcat6/app3/pid # chown app3:app3 /srv/tomcat6/app3/pid # chown -R app3:app3 /srv/tomcat6/app3 # chmod -R u=rwX,g=rX,o= /srv/tomcat6/app3 # chmod -R g+ws /srv/tomcat6/app3 ~~~ Il reste ensuite ajuster les ports AJP, HTTP, SHUTDOWN et les scripts de startup/shutdown. ### Unité systemd utilisateur Pour utiliser confortablement les instances on pourra utiliser systemd en mode utilisateur. Les développeurs pourront arrêter et démarrer l'instance d'eux-même. Pour faire ceci, il faut installer le paquet libpam-systemd (nécessite un reboot), et créer l'unité tomcat dans /etc/systemd/user/tomcat.service. ~~~ [Unit] Description=Tomcat %u. After=network.target [Service] WorkingDirectory=/home/%u Environment="CATALINA_BASE=/home/%u/tomcat" EnvironmentFile=/home/%u/tomcat/conf/env UMask=0002 ExecStart=/usr/share/tomcat7/bin/startup.sh ExecStop=/usr/share/tomcat7/bin/shutdown.sh ExecStopPost=/bin/sh -c date | /usr/bin/mail -s "%H/%u : Shutdown instance" foo@bar.com Type=forking [Install] WantedBy=default.target ~~~ Conserver la session de l'utilisateur. ~~~ # loginctl enable-linger foo ~~~ Enfin, l'utilisateur pour activer l'instance au démarrage et la démarrer, voir le status, … ~~~ $ systemctl --user enable tomcat $ systemctl --user start tomcat $ systemctl --user status -l tomcat $ systemctl --user restart tomcat $ systemctl --user stop tomcat ~~~ ## Oracle JDK Depuis le ?? le JDK propriétaire d'oracle n'est plus dans les dépôts Debian, il faut donc l'installer à la main. ~~~ update-alternatives --install "/usr/bin/java" "java" "/usr/local/opt/jdk1.6.0_30/bin/java" 1 update-alternatives --set java /usr/local/opt/jdk1.6.0_30/bin/java update-alternatives --install "/usr/bin/java" "java" "/usr/local/opt/jdk1.6.0_30/bin/java" 1 update-alternatives --set java /usr/local/opt/jdk1.6.0_30/bin/java update-alternatives --install "/usr/bin/keytool" "keytool" "/usr/local/opt/jdk1.6.0_30/bin/keytool" 1 update-alternatives --set keytool /usr/local/opt/jdk1.6.0_30/bin/keytool update-alternatives --install "/usr/bin/pack200" "pack200" "/usr/local/opt/jdk1.6.0_30/bin/pack200" 1 update-alternatives --set pack200 /usr/local/opt/jdk1.6.0_30/bin/pack200 update-alternatives --install "/usr/bin/rmid" "rmid" "/usr/local/opt/jdk1.6.0_30/bin/rmid" 1 update-alternatives --set rmid /usr/local/opt/jdk1.6.0_30/bin/rmid update-alternatives --install "/usr/bin/rmiregistry" "rmiregistry" "/usr/local/opt/jdk1.6.0_30/bin/rmiregistry" 1 update-alternatives --set rmiregistry /usr/local/opt/jdk1.6.0_30/bin/rmiregistry update-alternatives --install "/usr/bin/unpack200" "unpack200" "/usr/local/opt/jdk1.6.0_30/bin/unpack200" 1 update-alternatives --set unpack200 /usr/local/opt/jdk1.6.0_30/bin/unpack200 update-alternatives --install "/usr/bin/orbd" "orbd" "/usr/local/opt/jdk1.6.0_30/bin/orbd" 1 update-alternatives --set orbd /usr/local/opt/jdk1.6.0_30/bin/orbd update-alternatives --install "/usr/bin/servertool" "servertool" "/usr/local/opt/jdk1.6.0_30/bin/servertool" 1 update-alternatives --set servertool /usr/local/opt/jdk1.6.0_30/bin/servertool update-alternatives --install "/usr/bin/tnameserv" "tnameserv" "/usr/local/opt/jdk1.6.0_30/bin/tnameserv" 1 update-alternatives --set tnameserv /usr/local/opt/jdk1.6.0_30/bin/tnameserv update-alternatives --install "/usr/bin/jexec" "jexec" "/usr/local/opt/jdk1.6.0_30/bin/jexec" 1 update-alternatives --set jexec /usr/local/opt/jdk1.6.0_30/bin/jexec ~~~ En Wheezy JRE 7 ou ~~~ update-alternatives --install "/usr/bin/policytool" "policytool" "/usr/local/opt/jdk1.7.0_45/jre/bin/policytool" 1 update-alternatives --install "/usr/bin/appletviewer" "appletviewer" "/usr/local/opt/jdk1.7.0_45/bin/appletviewer" 1 update-alternatives --install "/usr/bin/extcheck" "extcheck" "/usr/local/opt/jdk1.7.0_45/bin/extcheck" 1 update-alternatives --install "/usr/bin/idlj" "idlj" "/usr/local/opt/jdk1.7.0_45/bin/idlj" 1 update-alternatives --install "/usr/bin/jar" "jar" "/usr/local/opt/jdk1.7.0_45/bin/jar" 1 update-alternatives --install "/usr/bin/jarsigner" "jarsigner" "/usr/local/opt/jdk1.7.0_45/bin/jarsigner" 1 update-alternatives --install "/usr/bin/javac" "javac" "/usr/local/opt/jdk1.7.0_45/bin/javac" 1 update-alternatives --install "/usr/bin/java" "java" "/usr/local/opt/jdk1.7.0_45/bin/java" 1 update-alternatives --install "/usr/bin/javadoc" "javadoc" "/usr/local/opt/jdk1.7.0_45/bin/javadoc" 1 update-alternatives --install "/usr/bin/javah" "javah" "/usr/local/opt/jdk1.7.0_45/bin/javah" 1 update-alternatives --install "/usr/bin/javap" "javap" "/usr/local/opt/jdk1.7.0_45/bin/javap" 1 update-alternatives --install "/usr/bin/jcmd" "jcmd" "/usr/local/opt/jdk1.7.0_45/bin/jcmd" 1 update-alternatives --install "/usr/bin/jconsole" "jconsole" "/usr/local/opt/jdk1.7.0_45/bin/jconsole" 1 update-alternatives --install "/usr/bin/jdb" "jdb" "/usr/local/opt/jdk1.7.0_45/bin/jdb" 1 update-alternatives --install "/usr/bin/jhat" "jhat" "/usr/local/opt/jdk1.7.0_45/bin/jhat" 1 update-alternatives --install "/usr/bin/jinfo" "jinfo" "/usr/local/opt/jdk1.7.0_45/bin/jinfo" 1 update-alternatives --install "/usr/bin/jmap" "jmap" "/usr/local/opt/jdk1.7.0_45/bin/jmap" 1 update-alternatives --install "/usr/bin/jps" "jps" "/usr/local/opt/jdk1.7.0_45/bin/jps" 1 update-alternatives --install "/usr/bin/jrunscript" "jrunscript" "/usr/local/opt/jdk1.7.0_45/bin/jrunscript" 1 update-alternatives --install "/usr/bin/jsadebugd" "jsadebugd" "/usr/local/opt/jdk1.7.0_45/bin/jsadebugd" 1 update-alternatives --install "/usr/bin/jstack" "jstack" "/usr/local/opt/jdk1.7.0_45/bin/jstack" 1 update-alternatives --install "/usr/bin/jstat" "jstat" "/usr/local/opt/jdk1.7.0_45/bin/jstat" 1 update-alternatives --install "/usr/bin/jstatd" "jstatd" "/usr/local/opt/jdk1.7.0_45/bin/jstatd" 1 update-alternatives --install "/usr/bin/native2ascii" "native2ascii" "/usr/local/opt/jdk1.7.0_45/bin/native2ascii" 1 update-alternatives --install "/usr/bin/rmic" "rmic" "/usr/local/opt/jdk1.7.0_45/bin/rmic" 1 update-alternatives --install "/usr/bin/schemagen" "schemagen" "/usr/local/opt/jdk1.7.0_45/bin/schemagen" 1 update-alternatives --install "/usr/bin/serialver" "serialver" "/usr/local/opt/jdk1.7.0_45/bin/serialver" 1 update-alternatives --install "/usr/bin/wsgen" "wsgen" "/usr/local/opt/jdk1.7.0_45/bin/wsgen" 1 update-alternatives --install "/usr/bin/wsimport" "wsimport" "/usr/local/opt/jdk1.7.0_45/bin/wsimport" 1 update-alternatives --install "/usr/bin/xjc" "xjc" "/usr/local/opt/jdk1.7.0_45/bin/xjc" 1 update-alternatives --set policytool /usr/local/opt/jdk1.7.0_45/jre/bin/policytool update-alternatives --set appletviewer /usr/local/opt/jdk1.7.0_45/bin/appletviewer update-alternatives --set extcheck /usr/local/opt/jdk1.7.0_45/bin/extcheck update-alternatives --set idlj /usr/local/opt/jdk1.7.0_45/bin/idlj update-alternatives --set jar /usr/local/opt/jdk1.7.0_45/bin/jar update-alternatives --set jarsigner /usr/local/opt/jdk1.7.0_45/bin/jarsigner update-alternatives --set javac /usr/local/opt/jdk1.7.0_45/bin/javac update-alternatives --set java /usr/local/opt/jdk1.7.0_45/bin/java update-alternatives --set javadoc /usr/local/opt/jdk1.7.0_45/bin/javadoc update-alternatives --set javah /usr/local/opt/jdk1.7.0_45/bin/javah update-alternatives --set javap /usr/local/opt/jdk1.7.0_45/bin/javap update-alternatives --set jcmd /usr/local/opt/jdk1.7.0_45/bin/jcmd update-alternatives --set jconsole /usr/local/opt/jdk1.7.0_45/bin/jconsole update-alternatives --set jdb /usr/local/opt/jdk1.7.0_45/bin/jdb update-alternatives --set jhat /usr/local/opt/jdk1.7.0_45/bin/jhat update-alternatives --set jinfo /usr/local/opt/jdk1.7.0_45/bin/jinfo update-alternatives --set jmap /usr/local/opt/jdk1.7.0_45/bin/jmap update-alternatives --set jps /usr/local/opt/jdk1.7.0_45/bin/jps update-alternatives --set jrunscript /usr/local/opt/jdk1.7.0_45/bin/jrunscript update-alternatives --set jsadebugd /usr/local/opt/jdk1.7.0_45/bin/jsadebugd update-alternatives --set jstack /usr/local/opt/jdk1.7.0_45/bin/jstack update-alternatives --set jstat /usr/local/opt/jdk1.7.0_45/bin/jstat update-alternatives --set jstatd /usr/local/opt/jdk1.7.0_45/bin/jstatd update-alternatives --set native2ascii /usr/local/opt/jdk1.7.0_45/bin/native2ascii update-alternatives --set rmic /usr/local/opt/jdk1.7.0_45/bin/rmic update-alternatives --set schemagen /usr/local/opt/jdk1.7.0_45/bin/schemagen update-alternatives --set serialver /usr/local/opt/jdk1.7.0_45/bin/serialver update-alternatives --set wsgen /usr/local/opt/jdk1.7.0_45/bin/wsgen update-alternatives --set wsimport /usr/local/opt/jdk1.7.0_45/bin/wsimport ~~~ ### Activation du « access_log » de Tomcat Pour loguer tous les accès, il suffit de décommenter cette partie dans le server.xml : ~~~{.xml} ~~~ ### Reverse proxy avec Apache Le but est de se passer du mod_jk est de faire un reverse proxy. --> Apache:80 --> Tomcat:8080 Activez le mod proxy et proxy_ puis modifier la configuration du module `mods-enabled/proxy.conf`. ~~~{.apache} ProxyRequests Off AddDefaultCharset off Order allow,deny Allow from all # Enable/disable the handling of HTTP/1.1 "Via:" headers. # ("Full" adds the server version; "Block" removes all outgoing Via: headers) # Set to one of: Off | On | Full | Block ProxyVia On ~~~ Puis dans le vhost concerné : ~~~{.apache} # FQDN principal ServerName myapp.webiste.com ProxyPass / ProxyPassReverse / Order allow,deny Allow from all ~~~ Note : attention à bien mettre le '/' final sous peine de s'arracher les cheveux avec un _Client denied by server configuration_ ### Installation du mod-jk d'Apache le mod-jk d'Apache permet de gérer la communication entre le serveur web Apache et le conteneur de servlets Tomcat. Pour l'installer : ~~~ # aptitude install libapache2-mod-jk ~~~ Éditez le fichier _/etc/libapache2-mod-jk/workers.properties_ : ~~~ # On utilise tomcat en version 6 workers.tomcat_home=/usr/share/tomcat6 # On utilise le moteur java de Sun workers.java_home=/usr/lib/jvm/java-6-sun # Liste des workers worker.list=app1_worker app2_worker #... # Paramètre pour le worker app1_worker worker.app1_worker.port=8009 worker.app1_worker.host=localhost worker.app1_worker.type=ajp13 ~~~ Ensuite, il faut créer le fichier de configuration Apache pour mod_jk, dans _/etc/apache2/conf.d/_ : ~~~ JkWorkersFile /etc/libapache2-mod-jk/workers.properties JkLogFile /var/log/apache2/mod_jk.log JkLogStampFormat "[%a %b %d %H:%M:%S %Y] " JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories JkRequestLogFormat "%w %V %T ~~~ Pour chaque application java, on crée un vhost Apache, en prenant le modèle suivant : ~~~{.apache} ServerName app1.evolix.net ServerAlias www.app1.evolix.net TransferLog /var/log/apache2/app1.log ErrorLog /var/log/apache2/app1_error.log JkMount /* app1_worker ~~~ Enfin, on s'assure que le tomcat écoute bien sur le port donné dans la configuration du worker (8009 dans l'exemple). Le fichier _/etc/tomcat6/server.xml_ doit contenir la ligne : ~~~{.xml} ~~~ Ne pas oublier de charger le module mod_jk et d'activer le nouveau vhost : ~~~ # a2enmod jk # a2ensite app1 ~~~ ### Manager Tomcat Une des méthodes possibles pour le déployment d'applications java est de le faire via une interface web, le manager Tomcat. Installation : ~~~ # aptitude install tomcat6-admin ~~~ Il faut ensuite ajouter un utilisateur au role _manager_, dans le fichier _/etc/tomcat6/tomcat-users.xml_ (équivalent d'un fichier htpasswd d'Apache) : ~~~ [...] ~~~ Une fois Tomcat redémarré, l'accès au manager ce fait sur l'URI : ### Connecteur HTTP Activer la compression gzip de certains types de fichiers : Dans le fichier _/etc/tomcat6/server.xml_, rajouter ceci dans le connecteur HTTP : ~~~ compression="on" compressionMinSize="2048" compressableMimeType="text/html,text/xml,text/plain,text/javascript,application/javascript" ~~~ ### FAQ Qu'est-ce que c'est JSVC ? Pourquoi l'utiliser ? JSVC est un outil permettant d'uniformiser le lancement de "daemon" en JAVA pour tous les systèmes, notamment sous Windows. Sous Linux, il est parfois utilisé, mais son utilisation reste déconseillée vu qu'il existe d'autres outils pour faire cela *et* que son utilisation ne permet pas une gestion via JMX. Sous Debian, il a été utilisé sous Debian Lenny, mais il ne sera plus utilisé dans les prochaines versions. Tomcat n'écoute pas en IPv4, pourquoi ? Comment le corriger ? Les versions récentes de Java préfèrent l'IPv6 si elle est présente. Le problème c'est que dans ce cas, il peut arriver que tomcat n'écoute pas en IPv4. Il faut alors modifier les propriétés par défaut en ajoutant ceci aux JAVA_OPTS : ~~~ -Djava.net.preferIPv4Stack=true ~~~