Railway.appはherokuの代替として注目されたPaaSで(枕言葉)、自分もfly.ioのVMでは重くて難しい処理をRailway.appの方に任せるという方法で無償運用している。
やってるのは数時間に一回、Redisを伴ったSidekiq/schedulerのワーカーを回してるだけで、回してるワーカー自体の負荷は毎回数分ということもあって大した負荷はないのだが、Railsを回してるだけでも結構メモリを喰ってしまう。5ドルを超えると有償になってしまうというのもあるので、なるべくこのメモリ使用量を減らしたい。そんなわけでいろいろやったことをつらつら。
MALLOC_ARENA_MAX=2
環境変数でMALLOC_ARENA_MAX = 2に指定しろというやつ。本当に意味があるかは正直不明。体感あるほど変わった印象はない。ちなみにherokuでは自動で2として設定されるらしい。
Webなど不必要なviewやコントローラーなど全部destroyして消した
これはかなり効果があった。一応動作テストで作ってたviewなどがあったため、自分の場合はwebは全てfly.io側で賄っていたのもあり、回していなかったページも全て消した。あと、ActionMailerなどもGASなどに肩代わりすることで消去。これらはかなり効果があった。
プロセスをフォークして切り捨てる
これは「Sidekiqのメモリが増え続ける問題対処」でまんま紹介されてる方のコードをそのまんまコピペしただけ。これについては劇的に効果があった。300MB前後でほとんど張りつくようになり、メモリの消費量の揺れがほとんどなくなった
Github Actionsで定期デプロイするようにした
メモリの待機消費量を劇的に減らす方法は「定期的に再起動すること」なんだけれど、システムでrails restartなどしてもほぼだめなのでどうしたらいいか相当迷ってた。しかしGithub Actionsでcronを指定した定期実行で、自動でデプロイするようにしたら待機でじわじわ増えるメモリをこれも激減した(もっと簡単な方法があるかもしれないが)
自動デプロイ自体はRailway.appの公式ブログでも設定例が紹介されている。Project Settingの設定のTokensの項目から、適当な名前でトークンを作る。それをgithubのリポジトリのSettings→Secrets and Variables→Actionsの項目にいき、New repository secretsから新しいトークン設定ページへ。RAILWAY_TOKENの名前で、先ほどのトークンを入力する。
その上で、.github/workflowsフォルダにymlファイルを作って、以下のコード。
name: Auto Redeploy
on:
schedule:
# 分 時 日 月 曜 日本時間はUTC時間に+9時間
- cron: '0 0 * * *'
- cron: '0 12 * * *'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Use Node 18
uses: actions/setup-node@v1
with:
node-version: 18.x
- name: Install packages
run: yarn install --frozen-lockfile
- name: Install Railway
run: npm i -g @railway/cli
- name: Deploy
run: railway up
timeout-minutes: 10
env:
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
自分はとりあえずこれで、cronの時間に自動でrailway.appにデプロイし直してくれる。もっとちゃんとした方法があるかも。