puma虽然自己的master的自己的进程守护机制,但在遇到极端情况还是会崩掉,需要一款进程守护工具来监视进程,在进程退出或者满足其他条件时做重启或其他操作。

进程守护类工具很很多,god、monit、eye、supervised等,使用monit是因为配置相对简单并且脱离了ruby环境,资源也占用少。

本文记录使用monit来守护puma和sidekiq两项服务进程,安装以及配置很简单。

环境

  • ubuntu 16.04
  • monit 5.1.6

安装

apt-get update
apt-get install monit -y

配置

编辑服务守护配置文件

vim /etc/monit/conf.d/app

写入配置

check process app_puma
  with pidfile /home/deploy/app/shared/tmp/pids/puma.pid
  start program = "/bin/sh -c 'cd /home/deploy/app/current; PATH=bin:/home/deploy/.rbenv/shims:/home/deploy/.rbenv/bin:$PATH LC_ALL=en_US.UTF-8 RAILS_ENV="production" bundle exec puma -q -e production -C config/puma.rb'"
    as uid "deploy" and gid "deploy"
    with timeout 60 seconds
  stop program = "/bin/sh -c 'cd /home/deploy/app/current; PATH=bin:/home/deploy/.rbenv/shims:/home/deploy/.rbenv/bin:$PATH LC_ALL=en_US.UTF-8 RAILS_ENV="production" bundle exec pumactl -F /home/deploy/app/current/config/puma.rb stop'"
    as uid "deploy" and gid "deploy"
    with timeout 60 seconds
  group app

check process app_sidekiq
  with pidfile /home/deploy/app/shared/tmp/pids/sidekiq.pid
  start program = "/bin/sh -c 'cd /home/deploy/app/current; PATH=bin:/home/deploy/.rbenv/shims:/home/deploy/.rbenv/bin:$PATH LC_ALL=en_US.UTF-8 RAILS_ENV="production" bundle exec sidekiq -d -e production -C /home/deploy/app/current/config/sidekiq.yml'"
    as uid "deploy" and gid "deploy"
    with timeout 120 seconds
  stop program = "/bin/sh -c 'cd /home/deploy/app/current; PATH=bin:/home/deploy/.rbenv/shims:/home/deploy/.rbenv/bin:$PATH LC_ALL=en_US.UTF-8 RAILS_ENV="production" bundle exec sidekiqctl stop /home/deploy/app/shared/tmp/pids/sidekiq.pid 11'"
    as uid "deploy" and gid "deploy"
    with timeout 120 seconds
  group app

重启服务

systemctl restart monit

问题解决

安装安之后,如果想要查看monit状态,需要输入以下命令:

# 查看详细状态
monit status
# 查看简介状态
monit summary

但这时候会出现一下提示信息:

/etc/monit/monitrc:290: Include failed -- Success '/etc/monit/conf-enabled/*'
Cannot translate '90h59yk0rdd5o' to FQDN name -- Name or service not known
Status not available - monit http interface is not enabled, please add the 'set httpd' statement

首先使用ifconfig查看内网ip,这里假如ip为192.168.1.2

打开 /etc/monit/monitrc, 注释掉配置的最后这一行 include /etc/monit/conf-enabled/*

查找2812这个字符,打开http服务,解除注释并修改如下几行配置:

set httpd port 2812
    use address 127.0.0.1  # 这里使用本地ip,只为开启状态查看,当然也可以使用公网ip,这样就可以公网打开web界面
    allow 127.0.0.1        # 允许哪些ip连接,这里设置本地
    allow admin:monit      # 用户名和密码

编辑 /etc/hosts文件,在最后加入一行 192.168.1.2 90h59yk0rdd5o 90h59yk0rdd5o.local.domain,其中90h59yk0rdd5o为提示信息中的主机名。

重启服务,问题解决。

关于使用部署工具

如果使用了mina或capistrano等工具部署,在部署完成后,需要重新执行如下命令让monit重新守护新进程:

sudo monit monitor all

但运行应用服务的用户都是非root用户,所以为了方便,需要设置一下,让这些用户执行sudo命令时不需要输入密码:

# 设置默认编辑器
update-alternatives --config editor
# 编辑sudoers文件
sudo visudo

# 在文件最后一行加入如下规则(假如用户是deploy)
deploy ALL=(ALL) NOPASSWD:ALL
%deploy ALL=(ALL) NOPASSWD:ALL

关于其他命令的使用可以使用monit --help查看。