ども。弊社ではRailsを使用しており、キューの非同期処理はShoryukenが実行しています。
そして、これまでそのShoryukenプロセスを常駐させていたのはGodでした。
ただこのGod、サーバがRebootされたときにうまくプロセス再起動されてこないんだけど?みたいな不具合がありました(最初に実装した担当者がもういない)。
Shoryukenを常駐させるのに、ぶっちゃけGodである必要は全然なく(笑)
「じゃあもうSupervisorとかで良くない?Godやめようぜ」となったのが今回の経緯です。
前提
SQS、Shoryuken、Godなどがどんなものかというお話は今回しません。
このあたりを参考にしてください。
環境
- Amazon Linux 2018.03
- Opsworks
- Chef
- AWS SQS
- 必要な環境変数はOpsworksのスタック上で定義
経緯
再度経緯を振り返ります。
- railsにてキューの非同期処理をShoryukenで実施している
- GodでShoryukenプロセスを常駐させていた
- サーバに再起動(もしくは停止・起動操作)が走るとShoryukenが自動で起動してこない
- 実装した担当者はもういない
- God使う必要あるの?という疑問
- Supervisorでよさそう、変えちゃえ。という結論に至る
要はGodを整備するよりSupervisorに乗り換えたほうがコストかからないっしょ、ということです。
yumでなぜ動かなかったか
supervisorには2系と3系とあり、このふたつでは諸々の違いが出てきてしまったようです。
Python2.6を無理に使用すればよい、ということらしいです。
じゃあ2系ように変換して書いていくか?と言われたら、「わざわざ古いバージョン使う理由が見当たらない」ので、3系に対応したほうがはやそうです。
yumでは3系がないので諦める
$ sudo yum info supervisor 読み込んだプラグイン:priorities, upgrade-helper 1053 packages excluded due to repository priority protections 利用可能なパッケージ 名前 : supervisor アーキテクチャー : noarch バージョン : 2.1 リリース : 9.el6 容量 : 292 k リポジトリー : epel/x86_64 要約 : A System for Allowing the Control of Process State on UNIX URL : http://www.plope.com/software/supervisor2/ ライセンス : ZPLv2.1 and BSD and MIT 説明 : The supervisor is a client/server system that allows its users to control a : number of processes on UNIX-like operating systems.
pipで3.xをインストールする
yumが使えないならpipです。実は公式でもpipを使えと書いてあります。
Introduction — Supervisor 3.3.4 documentation
- pipがなければインストールする
$ sudo easy_install pip
- supervisorインストール
pip install supervisor
余談
Supervisor3系は、基本的にPython2.7が使用されています。
# pip uninstall supervisor Uninstalling supervisor-3.3.4: /usr/bin/supervisorctl /usr/bin/supervisord /usr/local/bin/echo_supervisord_conf /usr/local/bin/pidproxy /usr/local/bin/supervisorctl /usr/local/bin/supervisord /usr/local/lib/python2.7/site-packages/supervisor-3.3.4-nspkg.pth /usr/local/lib/python2.7/site-packages/supervisor-3.3.4.egg-info /usr/local/lib/python2.7/site-packages/supervisor/childutils.py ...省略...
コンフィグなどを配置していく
自動生成されるもの
私が観測したものでいえば、Supervisorのインストールで作成されたファイルは以下のものです。
- /usr/bin/supervisorctl
- /usr/bin/supervisord
実際これだけでは動きませんので、必要なものを作成していきます。
トラブルシューティング
上記のファイルですが、サーバによって作成されないという怪奇現象がありました。
ということで、以下にはsupervisord, supervisorctlのファイル中身も記載しておきます。
init.dスクリプト
#!/bin/bash # # supervisord This scripts turns supervisord on # # Author: Mike McGrath <mmcgrath@redhat.com> (based off yumupdatesd) # # chkconfig: - 95 04 # # description: supervisor is a process control utility. It has a web based # xmlrpc interface as well as a few other nifty features. # processname: supervisord # config: /etc/supervisord.conf # pidfile: /var/run/supervisord.pid # # source function library . /etc/rc.d/init.d/functions RETVAL=0 start() { echo -n $"Starting supervisord: " daemon supervisord RETVAL=$? echo [ $RETVAL -eq 0 ] && touch /var/lock/subsys/supervisord } stop() { echo -n $"Stopping supervisord: " killproc supervisord echo [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/supervisord } restart() { stop start } case "$1" in start) start ;; stop) stop ;; restart|force-reload|reload) restart ;; condrestart) [ -f /var/lock/subsys/supervisord ] && restart ;; status) status supervisord RETVAL=$? ;; *) echo $"Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}" exit 1 esac exit $RETVAL
/etc/supervisor.conf
[inet_http_server] port = 127.0.0.1:9001 [unix_http_server] file=/tmp/supervisor.sock ; the path to the socket file ;chmod=0700 ; socket file mode (default 0700) ;chown=nobody:nogroup ; socket file uid:gid owner ;username=user ; default is no username (open server) ;password=123 ; default is no password (open server) [supervisord] logfile=/var/log/supervisor/supervisord.log ; main log file; default $CWD/supervisord.log logfile_maxbytes=50MB ; max main logfile bytes b4 rotation; default 50MB logfile_backups=10 ; # of main logfile backups; 0 means none, default 10 loglevel=info ; log level; default info; others: debug,warn,trace pidfile=/var/run/supervisord.pid ; supervisord pidfile; default supervisord.pid nodaemon=false ; start in foreground if true; default false minfds=1024 ; min. avail startup file descriptors; default 1024 minprocs=200 ; min. avail process descriptors;default 200 ;umask=022 ; process file creation umask; default 022 ;user=chrism ; default is current user, required if root ;identifier=supervisor ; supervisord identifier, default is 'supervisor' ;directory=/tmp ; default is not to cd during start ;nocleanup=true ; don't clean up tempfiles at start; default false ;childlogdir=/tmp ; 'AUTO' child log dir, default $TEMP ;environment=KEY="value" ; key value pairs to add to environment ;strip_ansi=false ; strip ansi escape codes in logs; def. false [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///var/tmp/supervisor.sock ; use a unix:// URL for a unix socket serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket ;username=chris ; should be same as in [*_http_server] if set ;password=123 ; should be same as in [*_http_server] if set ;prompt=mysupervisor ; cmd line prompt (default "supervisor") ;history_file=~/.sc_history ; use readline history if available [include] files = supervisord.d/*.ini ;ここは変更してもよい
shoryuken.sh
これは実際にShoryukenが実行されるためのスクリプトです。
Supervisorとは無関係に、Shoryukenが起動しているコマンドがあるはずなので書いていきます。
たとえばこういうやつです。
#自分の起動方法を書く exec /usr/local/bin/bundle exec shoryuken -R -C ./config/shoryuken.yml -L ./log/shoryuken.log -P ./log/shoryuken.pid
どうやってShoryukenが実行されているのかわからない場合は、プロセスを確認します。
ps aux | grep shoryuken
ここで作成したスクリプトをshoryuken.iniのcommand
で実行させることにします。
トラブルシューティング
このスクリプトでハマりました。
- 起動してもすぐに落ちるエラー
shoryuken.shによってShoryukenが起動するものの、落ちては起動する挙動を繰り返しました。
調査したところ、環境変数にMECAB_PATH
を定義せよとのことでした。
同じ現象が出た人は確認してみてください。
↓これを環境変数に定義する。
"MECAB_PATH": "/usr/local/lib/libmecab.so"
shoryuken.ini
Supervisorが、Shoryukenを起動するためのコンフィグです。
[program:shoryuken] command=sh /usr/local/bin/shoryuken.sh directory=path/to/file/execute/directory stdout_logfile=path/to/log/shoryuken.log redirect_stderr=true process_name=shoryuken startsecs=5 user=root numprocs=1 autostart=true autorestart=true
/usr/bin/supervisord
こちらのファイルが自動で生成されなかったとき用の保険で書いておきます。
#!/usr/bin/python from supervisor.supervisord import main # __doc__ required to make supervisord -h work from supervisor.supervisord import __doc__ main()
/usr/bin/supervisorctl
こちらのファイルが自動で生成されなかったとき用の保険で書いておきます。
#!/usr/bin/python from supervisor.supervisorctl import main # __doc__ required to make supervisorctl -h work from supervisor.supervisorctl import __doc__ main()
Godを削除する
これまで起動していたGodはこの段階でどこかに退避するか、削除してしまいましょう。
※削除ではなく退避をおすすめします。
起動する
基本はsupervisordの起動でShoryukenも起動してくるはずです。
$ /etc/init.d/supervisord start
$ supervisorctl status shoryuken RUNNING pid 20963, uptime 0:12:27
これで起動出来たと思います。プロセスも確認して、実行されていることを確認します。
$ ps aux | grep shoryuken
さらにログも確認します。
$ tail -f /var/log/supervisor/supervisor.log 2018-xx-xx xx:xx:xx,xxx INFO success: shoryuken entered RUNNING state, process has stayed up for > than 5 seconds (startsecs)
起動していればOKですね!
おわりに
今回はSupervisorを使うまでの話だったので、ここまでにします。
ここからChefなどで自動構築させる作業はありますが、動かすだけならこれで問題ないと思います!
※ansible派なのでつらい戦いになる