ElasticBeanstalkでRailsサーバPumaの無停止再起動を実現

Elastic Beanstalk

Elastic Beanstalkではデプロイ時にPumaが再起動してしまい、数秒ですがリクエストを裁けない時間ができてしまいます。PumaのWorker数の変更と、再起動のコマンドを少しいじります。

Pumaの無停止再起動(リクエストを捌きながら再起動する)

Pumaの再起動をするためには、Pumaの内部で複数のWorkerを起動しておく必要があります。

Puma Worker-1を再起動しているときは、Puma Worker-2でリクエストを捌いて、逆にPuma Worker-2が再起動している時には、Puma Worker-1でリクエストを捌くようなイメージで動かします。

  • Worker数の設定を変更
  • 再起動の設定を変更

の2つを設定していきましょう。

Worker数の設定を変更

Pumaで動くRailsアプリで、リクエスト処理しながらサーバ再起動をする
サーバの再起動をした時、一瞬でもサイトにアクセスできなくなると折角獲得したユーザを失うことになるかもしれません。 ...

の設定をします。

再起動の設定を変更

Elastic Beanstalkでは、「/opt/elasticbeanstalk/support/conf/puma.conf」に再起動に関する記述があるのですが、こちらを修正します。

置き換え用にファイル準備

description "Elastic Beanstalk Puma Upstart Manager"

start on runlevel [2345]
stop on runlevel [!2345]

respawn

script
exec /bin/bash <<"EOF"
  EB_SCRIPT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k script_dir)
  EB_SUPPORT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k support_dir)

  . $EB_SUPPORT_DIR/envvars
  . $EB_SCRIPT_DIR/use-app-ruby.sh
  if [ -f /etc/elasticbeanstalk/set-ulimit.sh ]; then
    . /etc/elasticbeanstalk/set-ulimit.sh
  fi
  if grep -qe 'true' /etc/elasticbeanstalk/has_puma.txt; then
    EB_APP_DEPLOY_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_deploy_dir)
    cd $EB_APP_DEPLOY_DIR
    if [ 0 -eq `ps aux | grep -e "puma" | grep -e "worker" | wc -l` ] ; then
      exec su -s /bin/bash -c "bundle exec puma -C $EB_SUPPORT_DIR/conf/pumaconf.rb" webapp
    else
      pkill -SIGUSR1 -f 'puma'
    fi
  else
    if [ 0 -eq `ps aux | grep -e "puma" | grep -e "worker" | wc -l` ] ; then
      exec su -s /bin/bash -c "puma -C $EB_SUPPORT_DIR/conf/pumaconf.rb" webapp
    else
      pkill -SIGUSR1 -f 'puma'
    fi
  fi
EOF
end script

 

.ebextensionの記述

先程用意したファイルをもとに、デプロイ時に置き換えるように、下記ファイルに追記します。

container_commands:
  01-change_puma_conf:
    command: cat .ebextensions/files/puma.conf > /opt/elasticbeanstalk/support/conf/puma.conf

コメント