問題
phoenixではデプロイするときにExrm(Elixir Release Manager)を使ってビルドする方法が推奨されているようで公式にも記載されている。
http://www.phoenixframework.org/v0.14.0/docs/advanced-deployment
上記のドキュメントに従って以下のように実行して
$ rel/hello_phoenix/bin/hello_phoenix start
wrk等のツールで以下のように負荷をかけて
$ wrk -t4 -c100 -d30S "http://localhost:4000/"
topでみてると天井知らずでメモリを食い潰して落ちる。
プロセス単位のGCが云々とはいったいなんだったのか。
解決
以下のようにdetachedオプションを付けて実行する。
$ rel/hello_phoenix/bin/hello_phoenix start -detached
考察
プロセスを見てみると以下のようになっている。
/your_directory/rel/hello_phoenix/erts-7.0/bin/run_erl -daemon /your_directory/rel/hello_phoenix/tmp/erl_pipes/hello_phoenix/ /your_directory/rel/hello_phoenix/log exec "/your_directory/rel/hello_phoenix/bin/hello_phoenix" "console"
startサブコマンドは具体的にはconsoleサブコマンドをdaemonオプションを付けて実行しているっぽい。
いったん話それて、Exrmを使わずに起動する別の手順が公式に載っていて
そっちには以下のような記述がある。
MIX_ENV=prod PORT=4001 iex -S mix phoenix.server
We can run our application detached from the iex console. This effectively daemonizes the process so it can run independently in the background. The command to do that looks like the following.
MIX_ENV=prod PORT=4001 elixir --detached -S mix phoenix.server
これの前者で実行すると同様にメモリが溢れる。これはコンソールにログを出力し続けるのでわかる。
つまりstartサブコマンドもdaemon化されてはいるけど裏側でログをバッファに(?)出力し続けてる様子。
Exrmを使わない方の後者ではdetachedオプションが使われてるので同様のことをすれば解決できるっぽい。
erlドキュメントを見てみるとdetachedオプションが載っている。
http://erlang.org/doc/man/erl.html
付けてみたら仮説通りメモリが溢れなくなった。
公式よ、書いといてくれ。