Mehrere tomcat Instanzen auf demselben Server

Manchmal will man mehrere tomcat Instanzen auf demselben Server betreiben, etwa mehrere Versionen oder Testumgebungen. Mit ein paar Handgriffen geht dies ganz leicht.

Zwei Dinge sind hier zu beachten:

  • tomcat braucht ein Basisverzeichnis in der Datei bin/catalina.sh
  • tomcat braucht mehere Ports

Passt man diese beiden Dinge jeweils an kann man beliebig viele tomcat Instanzen auf demselben Server Betreiben.

Als Beispiel installieren wir jeweils einen tomcat 8 und 9.

JAVA

Zuerst muss das JAVA-8 JDK heruntergeladen- und auf dem server nach /opt/java/ kopiert werden.
Dann gehts an die JAVA Installation:

cd /opt/java/
tar -xvzf jdk-?u??-linux-*.tar.gz
chown -vR root:root jdk1.8*
ln -sv jdk1.8.*/ 8

Tomcat

Als nächstes wird der tomcat Benutzer erstellt und zu diesem gewechselt:

useradd -c "tomcat user" -d /opt/tomcat/ tomcat
echo 'umask 0027' >> /opt/tomcat/.bashrc
su - tomcat
Der Rest wird nun als tomcat user gemacht!

Es folgt die tomcat 8 Installation:

wget 'http://www.eu.apache.org/dist/tomcat/tomcat-8/v8.?.?/bin/apache-tomcat-8.?.?.tar.gz'
tar -xvzf apache-tomcat-8.*.tar.gz
mv -v apache-tomcat-8.* tomcat8

Und das selbe für tomcat 9:

wget 'http://www.eu.apache.org/dist/tomcat/tomcat-9/v9.?.?/bin/apache-tomcat-9.?.?.tar.gz'
tar -xvzf apache-tomcat-9.*.tar.gz
mv -v apache-tomcat-9.* tomcat9

Nun werden die beiden tomcats konfiguriert.

Benutzer

Als erstes sollten die Benutzer konfiguriert werden, dazu in beiden tomcat Verzeichnissen die Datei: conf/tomcat-users.xml bearbeiten und zwischen
<tomcat-users[…]> und: </tomcat-users> folgendes einfügen:

<role rolename="admin-gui"/>
<role rolename="manager-gui"/>
<role rolename="tomcat"/>
<user username="tomcat" password="tomcat" roles="tomcat,manager-gui,admin-gui">

Verzeichnisse

Nun wird bei jeder tomcat Installation die Datei: bin/catalina.sh geöffnet und zupberst die folgenden Ungebungsvariablen gesetzt:

export JAVA_HOME=/opt/java/8
export CATALINA_HOME=/opt/tomcat/tomcat8
export CATALINA_BASE=/opt/tomcat/tomcat8

(für tomcat 9 muss bei CATALINA_HOME und CATALINA_BASE natürlich tomcat9 stehen! 😉 )

Ports

Nun geht es ans (um-)Konfigurieren der Ports.

Standardmässig nutzt tomcat diese 4 Ports:

Port Beschreibung
8005 Shutdown Port
8080 Connector Port
8443 Redirect Port
8009 AJP Connector Por

Der „Connector Port“ (8080) ist der Port, mit welchem zum Schluss die Webapplikation aufgerufen wird.
Die Anderen drei sind intern benötigte Ports.

Diese Ports müssen nun bei jedem tomcat in der Datei: conf/server.xml überall geändert werden.

Die Port Nummer ist egal, du kannst z.B. eine Nummer dazu zählen (8005 -> 8006), oder eine Nummer vorne anhängen: (8005 -> 18005), Hauptsache die Ports sind bei jeder tomcat Instanz unterschiedlich (und dürfen auf deinem Server natürlich noch nicht benutzt sein… 😉 )

Mittels der folgenden perl Zeile kannst du dies automatisch tun. Hier ein Beispiel für tomcat 8:

cd /opt/tomcat/tomcat8/
perl -pi -w -e 's/8005/8006/g;' conf/server.xml
perl -pi -w -e 's/8080/8081/g;' conf/server.xml
perl -pi -w -e 's/8443/8444/g;' conf/server.xml
perl -pi -w -e 's/8009/8010/g;' conf/server.xml

VirtualHosts

Wenn innerhalb des selben tomcat Servers mehrere unabhängige Applikationen laufen sollen, kann man noch ähnlich wie beim apache Webserver sog. VirtualHosts erstellen.

Dazu erstellt man zuerst im tomcat Basis-Verzeichnis das Verzeichnis für den virtuellen host:

mkdir -pv vhosts/app1

Nun muss in der Datei: conf/server.xml unter dem Block: <Host name=“localhost”[…]<Host> folgender Eintrag eingefügt werden:

<Host name="app1.example.net" appBase="vhosts/app1" unpackWARs="true" autoDeploy="true"></Host>

Start-/Stop

Nun kannst du beide tomcats mittels:

./bin/startup.sh
./bin/shutdown.sh

starten und stoppen.

Damit das zukünftig automatisch gemacht werden kann, erstellen wir hier noch ein redhat Konformes init.d-script, dies wieder mit dem root user.

Dazu wird zuerst die Konfigurationsdatei: /etc/default/tomcat erstellt:

RUNUSER="tomcat"
BASE_DIR="/opt/tomcat"
INSTANCES=( tomcat8 tomcat9 )

Diese Datei enthält drei Konfigurationen:

RUNUSER Der Benutzer unter welchem tomcat gestartet werden soll
BASE_DIR Das Verzeichnis wo all deine tomcats liegen
INSTANCES Das Verzeichnis mit den tomcats, ausgehend von BASE_DIR. In diesem Fall wird z.B. davon ausgegangen, dass tomcat8 in: /opt/tomcat/tomcat8 liegt.

Nun das eigentliche Startscript:

# chkconfig: - 80 05
# description: tomcat
#
 
# source functions library
. /etc/init.d/functions
 
 
APP_NAME=tomcat                                   # Name of the application (will be excecuted!)
APP_DESC="$APP_NAME application server"           # Short description
APP_DEFAULT=/etc/default/$APP_NAME                # Default conf file (sourced)
APP_PID=$(pgrep -f 'org.apache.catalina.startup.Bootstrap')
 
# source the configfile
if [ -f $APP_DEFAULT ]; then
  . $APP_DEFAULT
fi
 
if [ -z "$RUNUSER" ]; then
  echo "RUNUSER not specified in $APP_DEFAULT, will use owner of the $APP_NAME startscript as RUNUSER."
  echo_warning
fi
 
if [ -z "$BASE_DIR" ]; then
  echo "BASE_DIR not specified in $APP_DEFAULT"
  echo_failure
  exit 1
fi
 
if [ -z "$INSTANCES" ]; then
  echo "No $APP_NAME INSTANCES specified in $APP_DEFAULT"
  echo_failure
  exit 1
fi
 
 
case "$1" in
start)
  echo -n "Starting $APP_NAME..."
 
  #check in the proccess desc
  if  [ "$APP_PID" != "" ] ; then
    echo "proccess seems to be already running as: $APP_PID"
    echo_warning
    exit 2
  else
    # Start functions
    ERROR_COUNT=0
    for tomcat_instance in ${INSTANCES[@]}
    do
      init_script="$BASE_DIR/$tomcat_instance/bin/startup.sh"
      # If we have defined a runuser use it, otherwise run as owner of the start script
      if [ -z "$RUNUSER" ]; then
        RUNUSER=`stat -c '%U' $init_script`
      fi
 
      if [ -e $init_script ]; then
        $(which runuser) -l $RUNUSER $init_script > $BASE_DIR/$tomcat_instance/logs/startup.log 2>&1
        RETVAL=$?
        if [ $RETVAL -ne 0 ]; then
          ((ERROR_COUNT++))
        fi
      else
        echo "init-script: $init_script is not executable!"
        ((ERROR_COUNT++))
      fi
    done
    RETVAL=$ERROR_COUNT
 
    # Output OK or FAIL
    RETVAL=$?
    if [ $RETVAL -eq 0 ]; then
      echo_success
    else
      echo_failure
    fi
  fi
;;
 
 
 
stop)
  echo "Stopping $APP_NAME..."
 
# Stop functions
  if [ "$APP_PID" != "" ] ; then
    ERROR_COUNT=0
    for tomcat_instance in ${INSTANCES[@]}
    do
      init_script="$BASE_DIR/$tomcat_instance/bin/shutdown.sh"
      # Use the current running user of the proccess as shutdown user
      CURRENT_APP_PID=$(pgrep -f "catalina.base=$BASE_DIR/$tomcat_instance")
      RUNUSER=`ps -p $CURRENT_APP_PID -o user=`
 
      if [ -e $init_script ]; then
        $(which runuser) -l $RUNUSER $init_script > $BASE_DIR/$tomcat_instance/logs/shutdown.log 2>&1
        RETVAL=$?
        if [ $RETVAL -ne 0 ]; then
          ((ERROR_COUNT++))
        fi
      fi
    done
 
    if  [ "$APP_PID" != "" ] ; then
      echo "Some proccesses are still runing, please try: kill $APP_PID"
      ((ERROR_COUNT++))
    fi
 
    RETVAL=$ERROR_COUNT
 
    # Output OK or FAIL
    RETVAL=$?
    if [ $RETVAL -eq 0 ]; then
      echo_success
    else
      echo_failure
    fi
  else
    echo "$APP_NAME is not running"
  fi
;;
 
 
 
restart)
$0 stop && sleep 5 && $0 start || return=$0
;;
 
 
status)
  if [ -z "$APP_PID" ]; then
    echo "No $APP_NAME server is running."
  else
    echo -e "$APP_NAME server(s) are running with PIDs:\n$APP_PID"
  fi
  exit 0
;;
 
 
 
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
esac

Dieses kann man nun zum automatischen Starten konfigurieren:

chkconfig tomcat on

Referenzen

Published by

Steven Varco

Steven ist ein Redhat RHCE-Zertifizierter Linux-Crack und ist seit über 18 Jahren sowohl beruflich wie auch privat auf Linux spezialisiert. In seinem Keller steht ein Server Rack mit diversen ESX und Linux Servern.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.