3
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

マルチインスタンスな Tomcat と httpd を連携させるときにハマったこと

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

ポートの変更

/etc/tomcat1/conf/server.xml
...

<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" />

...

サービスの登録

/etc/systemd/system/tomcat1.service
[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
/etc/sysconfig/tomcat1
JAVA_HOME=/usr/local/java
CATALINA_BASE=/etc/tomcat1

tomcat2

環境定義の準備

# mkdir /etc/tomcat2
# cp -r /etc/tomcat1/*  /etc/tomcat2

ポートの変更

/etc/tomcat1/conf/server.xml
...

<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" />

...

サービスの登録

/etc/systemd/system/tomcat2.service
[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
/etc/sysconfig/tomcat2
JAVA_HOME=/usr/local/java
CATALINA_BASE=/etc/tomcat2

サービスの反映と起動

# systemctl daemon-reload
# systemctl start tomcat1
# systemctl start tomcat2

http://localhost:8081http://localhost:8082 にアクセスできれば成功です。firewalld にでも邪魔されていなければ問題なく見れると思います。

httpd との連携

httpd がインストールされており、 mod_proxymod_proxy_ajp が有効化されているものとします。いつものように proxy-ajp.conf にプロキシ設定を追加してみましょう:

/etc/httpd/conf.d/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 をつかいましょう

参考リンク

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
3
Help us understand the problem. What are the problem?