Fully Executable War
Spring Boot 1.3.0.RELEASEからSpring Bootのアプリケーションを単なるExecutable Warではなく、Fully Executable Warとして実行できるようになりました。
Executable Warの場合、systemdを利用しなければjavaで起動するためのシェルが必要でしたが、Fully Executable Warとすることでこういったシェルを作成する必要がなくなります。
Fully Executable Warの作成方法
spring-boot-maven-pluginをpluginに加え、executable設定をtrueにしてmvn installすると、Fully Executable Warが作成されます。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <version>1.3.1.RELEASE</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
Fully Executable Warの先頭に起動用のシェルが記載されています。
なおこのシェルはunzipやjar -xvfなどで解凍しても展開はされませんでした。
[user01@a12b89fed9fa /]$ more sample-api-1.0-SNAPSHOT.war
#!/bin/bash
#
# . ____ _ __ _ _
# /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
# ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
# \\/ ___)| |_)| | | | | || (_| | ) ) ) )
# ' |____| .__|_| |_|_| |_\__, | / / / /
# =========|_|==============|___/=/_/_/_/
# :: Spring Boot Startup Script ::
#
### BEGIN INIT INFO
# Provides: sample-api
# Required-Start: $remote_fs $syslog $network
# Required-Stop: $remote_fs $syslog $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: sample-api
# Description: Spring Boot Starter Parent
# chkconfig: 2345 99 01
### END INIT INFO
[[ -n "$DEBUG" ]] && set -x
# Initialize variables that cannot be provided by a .conf file
WORKING_DIR="$(pwd)"
[[ -n "$JARFILE" ]] && jarfile="$JARFILE"
[[ -n "$APP_NAME" ]] && identity="$APP_NAME"
〜以下略〜
echo "Usage: $0 {start|stop|restart|force-reload|status|run}"; exit 1;
esac
exit 0
〜以下バイナリ部〜
このシェルはspring-boot-maven-pluginによって埋め込まれているものです。
デフォルトでは以下のシェルが適用されます。
サービス化
warを適当な場所に配置して/etc/init.dにシンボリックリンクを張るだけでserviceで起動できるようになります。
ln -s /opt/spring/sample-api/current/lib/sample-api.war /etc/init.d/sample-api
chkconfig --add sample-api
service sample-api start
なお、service実行した時のjavaプロセスのユーザはwarファイルのオーナーになっています。
[user01@46399238b318 ~]$ ps -ef | grep spring.profiles.active
user01 2577 1 0 Dec27 ? 00:05:37 /usr/java/default/bin/java -Dsun.misc.URLClassPath.disableJarChecking=true -server -Dspring.profiles.active=local -jar /opt/spring/sample/current/lib/sample-api.war
runlevelや起動停止優先順位の変更
デフォルトだとrunlevelは2345、起動優先順は99、停止優先順は01になっています。
変更するには、以下のようにinitInfoChkConfigにchkconfigの値を設定します。
下の例ではrunlevelは2345、起動優先順は80、停優先順は20になります。
この機能はSpring Boot 1.3.1.RELEASEから利用可能です。
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
<embeddedLaunchScriptProperties>
<initInfoChkconfig>2345 80 20</initInfoChkconfig>
</embeddedLaunchScriptProperties>
</configuration>
</plugin>
JVMオプション、PID出力先などの変更
VM引数やPIDファイルの出力場所について設定をすることが可能です。
Fully Executable Warと同じ場所に、warファイルと同じ名称のconfファイルを作成しておくと、起動時に読み込まれます。
user01@a12b89fed9fa /]$ ls -lt /opt/spring/sample-api/current/lib/
合計 62200
-rwxr-xr-x 1 user01 user01 475 11月 7 23:59 2015 sample-api.conf
-rwxr-xr-x 1 user01 user01 63684691 11月 7 23:59 2015 sample-api.war
confに設定できる項目は公式のこちらに記載されています。
Fully Executable War内の起動シェルはconfファイルをsourceしているため、公式に記載されている項目以外にも環境変数を設定したり様々な処理を記載することもできます。
# Fully Executable War内の起動シェルの46行目付近
[[ -r "${jarfolder}/${configfile}" ]] && source "${jarfolder}/${configfile}"
例えば以下のようにumask 002を実行すると、ちゃんと出力ファイルが775のパーミッションで、出力されるようになります。
PID_FOLDER=/var/run/spring
LOG_FOLDER=/var/log/spring
umask 002
JAVA_HOME=/usr/java/jdk
JAVA_OPTS="-Dspring.profiles.active=local"