解決策
puma_worker_killer を入れた
https://github.com/zombocom/puma_worker_killer
ひとことで言うと、worker を殺して回る gem
なので定期的にメモリを解放してくれる
手順
1.Gemfileに以下を追加します:
gem 'puma_worker_killer'
2.Bundle installを実行します:
bundle install
3.Pumaの設定ファイル(通常はconfig/puma.rb
)に以下を追加します:
before_fork do
require 'puma_worker_killer'
PumaWorkerKiller.config do |config|
config.ram = 1024 # total RAM available
config.frequency = 5 # how often to check
config.percent_usage = 0.98 # percent of RAM to use before killing
config.rolling_restart_frequency = 12 * 3600 # 12 hours in seconds
end
PumaWorkerKiller.start
end
puma_worker_killer の設定値の解説
config.ram = 1024
: アプリケーションが利用可能なRAMの総量
config.frequency = 5
: メモリの使用状況をどのくらいの頻度でチェックするか。5秒ごとにメモリ使用状況をチェックする。
config.percent_usage = 0.98
: メモリの使用率がどの程度になったらワーカーを終了(kill)するか。メモリ使用率が98%に達したらワーカーを終了する。
config.rolling_restart_frequency = 12 * 3600
: 定期的なワーカーの再起動を行う間隔。12時間ごとにワーカーを再起動する。
起こったことを時系列で
ユーザーがいないサーバーが落ちる
render.com (ホスティングサービス)を使用してデプロイしたRailsアプリケーションが時間が経つと落ちるという奇妙な現象に遭遇しました。
メモリ使用量が急落してきれいに崖になっている部分で落ちています。
リスタートがかかってメモリが解放されたようです。
調査
やったこと:
malloc というのが悪さをしているらしいので、MALLOC_ARENA_MAX=2 という環境変数を設定して監視してみる
結果:
うまくいかなかった。変化無し
やったこと:
mallocの代わりにjemallocを使ってRubyをコンパイル
結果:
サーバーは落ちなくなった。でもメモリ使用量が高いまま。
どうやら定期的に worker を再起動しているぽい。(なぜ jemalloc にして落ちなくなったのかは不明。)
やったこと:
puma_worker_killer を導入(冒頭の解決策、手順に同じ)
結果:
メモリ使用量めちゃくちゃ減った
これで一安心だけど、レスポンスは悪くなる
感想
worker 殺して回るのはちょっと抵抗あるけど調査難航しそうだし、パフォーマンスもそこまでシビアではないので当分はこれで凌ぐ予定