Herokuで稼働しているアプリのApplicationServerをunicornからpumaに変更することにした。
理由は、Capybaraを3系にアップグレードしようとしたところ、デフォルトのサーバがpumaらしく、このまま放っておくとテスト系のライブラリもレガシー化していきそうだなと思ったため。
やったこと
unicorn系の削除
まず、Gemfileからunicorn系のgemの削除を行った。
unicornの設定ファイル、unicorn-worker-killerの設定の削除も忘れずに。
pumaのインストール
- Gemfileにpumaを追加
- config/puma.rbを作成
- Procfileの修正
config/puma.rbは、Herokuのサイトを参考に行った。
デプロイしてみる
これでデプロイしてみた。Herokuで利用しているDynoはStandard-2Xのため、以下のサイトの情報を読んで、WEB_CONCURRENCY
を3、RAILS_MAX_THREADS
を5に設定しておいた。
これで1日様子見してみた。
修正を試みる
1日経って、R14のWarningが結構発生していた。R14はメモリの使いすぎでスワップが発生している状態なので、よろしくない。暫定的にRAILS_MAX_THREADS
を4に落とした後、Herokuのドキュメントを読んでみる。
puma_worker_killerを入れる
pumaの使用メモリが多すぎたことが原因なので、puma_worker_killerを入れて定期的に再起動させることにした。
gem 'puma' gem 'puma_worker_killer'
これをbundle install
する。
そして、config/initializers/puma_worker_killer.rb
に以下を追加。
PumaWorkerKiller.enable_rolling_restart
jemallocのbuildpackを入れる
Herokuのドキュメントに、マルチスレッド環境ではjemallocを使ったら効果があると書かれていたので、入れてみる。 RubyKaigi2018でも、jemallocは効果的だという話だった。
しかし、Herokuだと使えないよなーと思っていたら、buildpackがあることを知ってびっくりした。ありがたい〜。
2020-07-14 追記
紹介していたbuildpackがメンテナンス終了していました。新しくforkされた方を使いましょう。
メンテ終了… elements.heroku.com
forkされた方 github.com
まず、jemallocのbuildpackを入れる。新しい方にURLは変えてありますのでご安心を。
heroku buildpacks:add --index 1 https://github.com/gaffneyc/heroku-buildpack-jemalloc/ --app app_name
次に、Procfileを以下のように修正した。
web: jemalloc.sh bundle exec puma -C config/puma.rb
そして、デプロイ。
git push heroku master
とりあえず、これで様子を見てみることにする。
追記
WEB_CONCURRENCY
を3、RAILS_MAX_THREADS
を5に設定しておいた。
と書いていたが、結局R14がまた発生したため、WEB_CONCURRENCY
は2に変更した。
2019-07-26 追記
設定が不完全だったので、ちゃんと設定した。
2020-07-14 追記
jemallocの新しいバージョンが使えるbuildpackが出ていました。