Playのアプリ起動をMacOSXのlaunchdで制御する
最近は落雷のせいで電源が瞬断し、UPSのような高級なものは使っておりませんので、常時起動のMac miniが落ちてしまうことが何度か発生しています。
そして、再起動後、Playのアプリが起動してくれません。launchdでアプリを制御しているので、再起動すれば問題ないはずなのです。
原因は単純で、RUNNING_PIDが残ってしまっているからです。
では、どのように解決すれば良いのでしょうか。
RUNNING_PIDを作らないようにする
デフォルトでは、アプリを実行するカレントディレクトリにRUNNING_PIDが作られます。これがpidファイルです。
システムプロパティ"pidfile.path"に任意のパスを設定すると、そのパスのファイルがRUNNING_PIDの代わりにpidファイルになります。
さらに、このプロパティを処理するコード(NettyServer.scala:L.211)を見てみると...どうやら、このプロパティに"/dev/null"を設定すると、pidファイルを無視してくれそうです。
- 起動(distしたアプリのstartスクリプト)
$ ./start -Dpidfile.path=/dev/null ...(正しく起動されたらしいメッセージが出力される) $ ll RUNNING_PID ls: RUNNING_PID: No such file or directory $
- 参考:startスクリプトの最終行
exec java $* -cp $classpath play.core.server.NettyServer `dirname $0`
当然ですが、多重起動した場合はportエラーが出るようになります。
launchdで起動したらlaunchdで落とす
playのstopコマンドは、RUNNING_PIDに書いてあるpidのプロセスをkillしてRUNNING_PIDを消す、という動作です。
launchdではpidを管理していますので、わざわざpidを保存する必要は無く、停止させるときはlaunchdで停止(launchctl stop
- おまけ:start用のplistファイル(app1)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Disabled</key> <false/> <key>KeepAlive</key> <false/> <key>Label</key> <string>local.app1</string> <key>ProgramArguments</key> <array> <string>/var/playapp/app1/start</string> <string>-Dpidfile.path=/dev/null</string> </array> <key>RunAtLoad</key> <true/> <key>UserName</key> <string>root</string> </dict> </plist>