Tomcat8のマルチインスタンス化

# 環境

[前回(Apache+Tomcat8をセットアップする)](https://qiita.com/ochiba/items/3bba16a8d2a2bc1fc1d2)の続き。
前回時点で起動させていたtomcatは停止しておく。

```
# systemctl stop tomcat.service
```

1台のサーバに複数のTomcat8インスタンスを起動し、mod_jkでロードバランスする環境をセットアップする。


## マルチインスタンス化で考慮すること

同一サーバ上で起動する場合、最低限以下の設定をインスタンス毎に修正すればよい。

* `CATALINA_BASE`
  * Tomcatインスタンス用のディレクトリ。このパスをもとにconfやwebappsなどのディレクトリのパスを解決する。
  * `CATALINA_HOME`はTomcatのインストールディレクトリなのでこちらは変更しない。
* `CATALINA_PID`
  * TomcatインスタンスのPIDを記録するファイル。
  * catalina.shが操作対象のプロセスを特定する際に利用する。
* conf/server.xml
  * Tomcatインスタンスの動作設定。
  * インスタンス間でListen Portが被らないように修正する。

今回は2インスタンスを以下のように設定していく。

|Key|svr00|svr01|
|:--|:--|:--|
|`CATALINA_BASE`|/var/lib/tomcats/svr00|/var/lib/tomcats/svr01|
|`CATALINA_PID` |/run/tomcat/tomcats-svr00.pid|/run/tomcat/tomcats-svr01.pid|
|Listen Port(Shutdown)|9005|9015|
|Listen Port(AJP)     |9001|9011|


# Tomcat8のマルチインスタンス化

## テンプレートUnitの作成

Unitファイルは前回作成したものを流用して作成。
参考:[10.6.5. インスタンス化されたユニットの使用](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-unit_files#sect-Managing_Services_with_systemd-Instantiated_Units)

```ini:/etc/systemd/system/tomcats@.service
[Unit]
Description=Apache Tomcat Web Application Container for %I
After=syslog.target network.target

[Service]
User=tomcat
Group=tomcat
Type=forking
Environment="NAME=%I"
EnvironmentFile=/etc/sysconfig/tomcats-%I
ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target
```

tomcat.serviceとの差分は以下の通り。

```diff
-Description=Apache Tomcat Web Application Container
+Description=Apache Tomcat Web Application Container for %I

-EnvironmentFile=/etc/sysconfig/tomcat
+Environment="NAME=%I"
+EnvironmentFile=/etc/sysconfig/tomcats-%I
```

`%I`はユニット指定子の1つで`tomcats@svr00.service`とインスタンス化した場合、`%I`の部分は`svr00`として解決される。
Unitファイルを作成したらsystemdに読み込み。

```shell-session
# systemctl daemon-reload
```


## svr00の立ち上げ

svr00用のディレクトリの作成と設定ファイルのコピー。

```shell-session
# mkdir -p /var/lib/tomcats/svr00/{logs,temp,webapps,work}
# mkdir -p /var/lib/tomcats/svr00/webapps/examples
# cp -r /opt/tomcat/conf /var/lib/tomcats/svr00/
# chown -R tomcat:tomcat /var/lib/tomcats/svr00
```

JSPのサンプルファイルを配置。

```html:/var/lib/tomcats/svr00/webapps/examples/index.jsp
<!DOCTYPE html>
<html>
    <head>
        <title>Checker</title>
    </head>
    <body>
        <h1>NAME: <%= System.getenv("NAME")%></h1>
        <h1>HTTP_HOST: <%= request.getHeader("Host")%></h1>
    </body>
</html>
```

Listen Portの編集。

```xml:/var/lib/tomcats/svr00/conf/server.xml(抜粋)
<Server port="9005" shutdown="SHUTDOWN">
    <Connector port="9001" protocol="AJP/1.3" />
```

svr00用の環境変数定義ファイルの作成。

```bash:/etc/sysconfig/tomcats-svr00
JAVA_HOME="/usr/lib/jvm/jre"
CATALINA_PID="/run/tomcat/tomcats-svr00.pid"
CATALINA_HOME="/opt/tomcat"
CATALINA_BASE="/var/lib/tomcats/svr00"
CATALINA_OPTS="-Xms512M -Xmx1024M -server -XX:+UseParallelGC"
JAVA_OPTS="-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom"
```

svr00の起動。

```shell-session
# systemctl start tomcats@svr00.service
# systemctl status tomcats@svr00.service
● tomcats@svr00.service - Apache Tomcat Web Application Container for svr00
   Loaded: loaded (/etc/systemd/system/tomcats@.service; disabled; vendor preset: disabled)
   Active: active (running) since Sun 2019-04-21 06:31:07 UTC; 1min ago
  Process: 5225 ExecStart=/opt/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
 Main PID: 5233 (java)
   CGroup: /system.slice/system-tomcats.slice/tomcats@svr00.service
           └─5233 /usr/lib/jvm/jre/bin/java -Djava.util.logging.config.file=...
// active (running)になっていること

# cat /run/tomcat/tomcats-svr00.pid
5233
// ファイルが存在してsystemdが認識しているPIDが記録されていること
```

## svr01の立ち上げ

svr01用のディレクトリの作成と設定ファイルのコピー。

```shell-session
# mkdir -p /var/lib/tomcats/svr01/{logs,temp,webapps,work}
# mkdir -p /var/lib/tomcats/svr01/webapps/examples
# cp -r /opt/tomcat/conf /var/lib/tomcats/svr01/
# chown -R tomcat:tomcat /var/lib/tomcats/svr01
```

JSPのサンプルファイルを配置。

```
# cp /var/lib/tomcats/svr0{0,1}/webapps/examples/index.jsp
```

Listen Portの編集。

```xml:/var/lib/tomcats/svr01/conf/server.xml(抜粋)
<Server port="9015" shutdown="SHUTDOWN">
    <Connector port="9011" protocol="AJP/1.3" />
```

svr01用の環境変数定義ファイルの作成。

```bash:/etc/sysconfig/tomcats-svr01
JAVA_HOME="/usr/lib/jvm/jre"
CATALINA_PID="/run/tomcat/tomcats-svr01.pid"
CATALINA_HOME="/opt/tomcat"
CATALINA_BASE="/var/lib/tomcats/svr01"
CATALINA_OPTS="-Xms512M -Xmx1024M -server -XX:+UseParallelGC"
JAVA_OPTS="-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom"
```

svr01の起動。

```shell-session
# systemctl start tomcats@svr01.service
# systemctl status tomcats@svr01.service
● tomcats@svr01.service - Apache Tomcat Web Application Container for svr01
   Loaded: loaded (/etc/systemd/system/tomcats@.service; disabled; vendor preset: disabled)
   Active: active (running) since Sun 2019-04-21 07:22:50 UTC; 4s ago
  Process: 5576 ExecStart=/opt/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
 Main PID: 5584 (java)
   CGroup: /system.slice/system-tomcats.slice/tomcats@svr01.service
           └─5584 /usr/lib/jvm/jre/bin/java -Djava.util.logging.config.file=...
// active (running)になっていること

# cat /run/tomcat/tomcats-svr01.pid
5584
// ファイルが存在してsystemdが認識しているPIDが記録されていること
```


# mod_jkによるロードバランシング
## Apacheの設定変更

`DirectoryIndex`にindex.jspを追加。

```diff:/etc/httpd/conf/httpd.conf
 <IfModule dir_module>
-    DirectoryIndex index.html
+    DirectoryIndex index.html index.jsp
 </IfModule>
```

svr01用のworkerを追加し、LBに組み込む。

```diff:/etc/httpd/conf.d/workers.properties
+# Define Node2
+worker.node2.type=ajp13
+worker.node2.host=127.0.0.1
+worker.node2.port=9011
+worker.node2.ping_mode=A
+worker.node2.lbfactor=1
+
 # Define Load-balancer
 worker.lb.type=lb
-worker.lb.balance_workers=node1
+worker.lb.balance_workers=node1,node2
 worker.lb.sticky_session=1
```

設定の変更を反映。

```shell-session
# apachectl configtest
Syntax OK
# systemctl reload httpd.service
```

## 確認

http://127.0.0.1:9000/examples/ にアクセスし、NAMEとHTTP_POSTの2行が表示されること。
何度か更新することでNAMEがsvr00とsvr01に切り替わればOK。


# 自動起動設定

動作確認が済んだらhttpd、tomcatの各サービスについて自動起動を有効にする。

```shell-session
# systemctl enable httpd.service tomcats@svr00.service tomcats@svr01.service
```