tomcat をマルチインスタンス化する
環境変数 CATALINA_BASE を変更することで複数の Tomcat インスタンスを同時に起動できます。
/bin/catalina.sh run を複数回実行しても Tomcat インスタンスを増やすことはできません。ポートの衝突が発生するためです。しかし conf/server.xml には Tomcat が利用するポートを指定する項目があります。conf/ の設定ファイル類は CATALINA_BASE に指定されたパスから相対パスで検索されますから、インスタンスごとに CATALINA_BASE を切り替えてしまいましょう。
実際にやってみる
まずは Tomcat をマルチインスタンス化しましょう。yum install tomcat で Tomcatを導入した場合はデフォルトでマルチインスタンス化に対応しています(参考)。以下では wget などでバイナリを入手して設置している場合の方法をご紹介します。なお、JDK が /usr/local/java 、Tomcat 本体が /usr/local/tomcat に配置してある想定です。
tomcat1
環境定義の準備
# mkdir /etc/tomcat1
# cp -r /usr/local/tomcat/conf /etc/tomcat1
# cp -r /usr/local/tomcat/logs /etc/tomcat1
# cp -r /usr/local/tomcat/temp /etc/tomcat1
# cp -r /usr/local/tomcat/webapps /etc/tomcat1
# cp -r /usr/local/tomcat/work /etc/tomcat1
ポートの変更
...
<Server port="8015" shutdown="SHUTDOWN">
...
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
-->
<Connector port="8081" protocol="HTTP/1.1"
connectionTimeout="20000" />
...
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8019" protocol="AJP/1.3" />
...
サービスの登録
[Unit]
Description=Tomcat1: Apache Tomcat Servlet Container
After=syslog.target network.target
[Service]
Type=forking
EnvironmentFile=/etc/sysconfig/tomcat1
ExecStart=/usr/local/tomcat/bin/startup.sh
ExecStop=/usr/local/tomcat/bin/shutdown.sh
KillMode=none
[Install]
WantedBy=multi-user.target
JAVA_HOME=/usr/local/java
CATALINA_BASE=/etc/tomcat1
tomcat2
環境定義の準備
# mkdir /etc/tomcat2
# cp -r /etc/tomcat1/* /etc/tomcat2
ポートの変更
...
<Server port="8025" shutdown="SHUTDOWN">
...
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
-->
<Connector port="8082" protocol="HTTP/1.1"
connectionTimeout="20000" />
...
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8029" protocol="AJP/1.3" />
...
サービスの登録
[Unit]
Description=Tomcat2: Apache Tomcat Servlet Container
After=syslog.target network.target
[Service]
Type=forking
EnvironmentFile=/etc/sysconfig/tomcat2
ExecStart=/usr/local/tomcat/bin/startup.sh
ExecStop=/usr/local/tomcat/bin/shutdown.sh
KillMode=none
[Install]
WantedBy=multi-user.target
JAVA_HOME=/usr/local/java
CATALINA_BASE=/etc/tomcat2
サービスの反映と起動
# systemctl daemon-reload
# systemctl start tomcat1
# systemctl start tomcat2
http://localhost:8081 と http://localhost:8082 にアクセスできれば成功です。firewalld にでも邪魔されていなければ問題なく見れると思います。
httpd との連携
httpd がインストールされており、 mod_proxy と mod_proxy_ajp が有効化されているものとします。いつものように proxy-ajp.conf にプロキシ設定を追加してみましょう:
<location /docs >
ProxyPass ajp://localhost:8019/docs
</location>
<location /examples >
ProxyPass ajp://localhost:8029/examples
</location>
# sudo systemctl restart httpd
しかし、この状態だと正常にプロキシされません。 httpd が以下のようなエラーを吐いていることが確認できるはずです:
[Tue Sep 10 21:47:48.938608 2019] [proxy:error] [pid 4646] (13)Permission denied: AH00957: AJP: attempt to connect to 127.0.0.1:8019 (localhost) failed
[Tue Sep 10 21:47:48.938745 2019] [proxy:error] [pid 4646] AH00959: ap_proxy_connect_backend disabling worker for (localhost) for 60s
[Tue Sep 10 21:47:48.938773 2019] [proxy_ajp:error] [pid 4646] [client ***.***.***.*:*****] AH00896: failed to make connection to backend: localhost
AJP のポートをデフォルトの 8009 から変更したことで SELinux に怒られてしまいました。setsebool で許可してあげましょう:
# sudo /usr/sbin/setsebool httpd_can_network_connect true
結論
めんどくさいのでつかえるなら Docker をつかいましょう