1. amedama

    Posted

    amedama
Changes in title
+Django + v(irtual)env + Celery + Supervisor
Changes in tags
+Python
2.7
+Django
1.6.5
+Celery
3.1.8
Changes in body
Source | HTML | Preview
@@ -0,0 +1,172 @@
+まとめる時間をとりたくないのであっさりとメモっぽく。
+
+
+# 環境
+
+```
+> lsb_release -a
+No LSB modules are available.
+Distributor ID: Debian
+Description: Debian GNU/Linux 7.6 (wheezy)
+Release: 7.6
+Codename: wheezy
+```
+
+別件でSupervisorをsidからソース取ってきた```3.0r1-1~bpo70+1```にしています。
+Ubuntu 12.04でもそうですが、元々の3.0a8というのが相当古いらしいためです (2010年)。
+Ubuntu 14.04だと3.0b2で、ちょっと新しい (2013年?)
+
+今なら 3.1.2 でしょうか。……リリース日、2014-09-07って(本稿執筆の)3日前じゃん
+
+参考: http://supervisord.org/changes.html
+
+# 何がしたいか
+
+Django初級であれば
+
+* Python 2.7 -> apt
+* Django -> apt
+* Celery -> apt
+* django-celery -> apt-get
+
+でも、いいと思うんですが、少しアグレッシブに
+
+* Python 2.7 -> venv中でpip
+* Django -> venv中でpip
+* Supervisor -> apt
+* Celery -> venv中でpip
+
+とかしてみたかったのです。OS標準パッケージへの依存を減らしたい。
+
+ここで Supervisor だけ pipではないのは /etc/init.d/supervisor とか欲しいからです。
+
+開発環境の別のテストプロジェクトとか
+(Apacheからリバースプロキシ的に起動する)tornadoのプロジェクトとかも
+このaptにくっついたSupervisorで一括して管理する点では問題はなさそうなので、
+このようにします。
+
+で、要は「Supervisorを使ってvenv内のDjango経由でCeleryのワーカを常駐させる」必要があります。
+
+もともとの(dj)celeryの設定は```/etc/default/celeryd```にあります。
+あいにくこれはbash(```/etc/init.d/celeryd```)から呼ばれるファイルなので、
+Supervisorの設定に変換しなければなりません。
+
+これを行う際、注意する必要があったポイントをさっくり書いとくので何かヒントになれば幸いです。
+
+## その(環境)変数は誰のものか
+
+CELERY_OPTSなどをSupervisorの設定に入れても意味がありません。
+言い換えると、```/etc/init.d/celeryd```内の定数っぽいものには
+
+* Supervisorにも渡す必要がある環境変数
+* /etc/init.d/celeryd が食うだけの一時的な環境変数
+
+の2種類がしれっと混じっています。区別はソースを見るしかありません。
+
+## manage.py celeryd_multi は分解してmanage.py celery worker にわけてSupervisorの設定とする。
+
+特に(Celeryの)ワーカが複数あったりする場合、
+キューやらワーカやらの設定を```/etc/default/celeryd```に書くんですが、
+celeryd_multiはSupervisordと相性はあんまりよくないようです。
+
+djceleryのceleryd_multi実態はCeleryのcelery-multi
+をDjangoの設定を受け継ぎつつ実行するものです (celeryd_multi.py 見るとそうなってる)。
+
+Celeryのcelery-multiコマンドは「workerを起動する」です。
+
+単純な"Django + Celery"構成でも、
+psで残るプロセスに ".../manage.py celery-multi" といったプロセスはありません。
+全部 ".../manage.py celery worker" が複数デーモンとして生きているはずです。
+
+という感じで、manage.py celeryd_multi をSupervisor上で動かそうとするのは、ダメそう。
+
+参考:http://stackoverflow.com/questions/15558875/running-celeyd-multi-with-supervisor
+
+## 設定例
+
+```text:/etc/default/celery
+ENABLED="true"
+CELERYD_LOG_LEVEL="DEBUG"
+CELERY_TIMEZONE='Asia/Tokyo'
+CELERYD_NODES="manage build"
+CELERYD_CHDIR="/opt/griflet/"
+
+CELERYD_MULTI="$CELERYD_CHDIR/manage.py celeryd_multi"
+CELERYCTL="$CELERYD_CHDIR/manage.py celeryctl"
+# XXXX は数字にする
+CELERYD_OPTS="--time-limit=XXXX --time-limit:build=XXXX -c 1 -Q:build build -Q manage"
+CELERY_CONFIG_MODULE="myproject.celeryconfig"
+
+CELERYD_LOG_FILE="/var/log/celery/%n.log"
+CELERYD_PID_FILE="/var/run/celery/%n.pid"
+
+CELERYD_USER="myproject"
+CELERYD_GROUP="myproject"
+
+export DJANGO_SETTINGS_MODULE="myproject.settings"
+```
+
+なら、だいたい以下のような感じ。ただし検証はしてません。
+
+```text:conf.d/myproject.conf
+[program:celery-myproject-manage]
+command=/opt/myproject/venv/bin/python /opt/myprojcet/manage.py celery worker
+ --loglevel=DEBUG
+ -Q manage
+ --logfile=/var/log/celery/manage.log
+ --pidfile=/var/run/celery/manage.pid
+ --hostname manage@hostname
+ --concurrency 1
+ --time-limit=XXXX
+ --workdir=/opt/myproject/
+
+user=myprojcet
+directory=/home/myprojcet
+numprocs=1
+stdout_logfile=/var/log/celery/manage.stdout.log
+stderr_logfile=/var/log/celery/manage.stderr.log
+autostart=true
+autorestart=true
+startsecs=10
+environment =
+ DJANGO_SETTINGS_MODULE="myprojcet.settings",
+ CELERY_TIMEZONE="Asia/Tokyo"
+
+
+[program:celery-myprojcet-build]
+command=/opt/myprojcet/venv/bin/python /opt/myprojcet/manage.py celery worker
+ --loglevel=DEBUG
+ -Q build
+ --logfile=/var/log/celery/build.log
+ --pidfile=/var/run/celery/build.pid
+ --hostname build@hostname
+ --concurrency 1
+ --time-limit=XXXX
+ --workdir=/opt/myprojcet/
+
+user=myprojcet
+directory=/home/myprojcet
+numprocs=1
+stdout_logfile=/var/log/celery/build.stdout.log
+stderr_logfile=/var/log/celery/build.stderr.log
+autostart=true
+autorestart=true
+startsecs=10
+environment =
+ DJANGO_SETTINGS_MODULE="myprojcet.settings",
+ CELERY_TIMEZONE="Asia/Tokyo",
+```
+
+## Supervisord側で動いたら
+
+環境変数にSUPERVISORなんちゃらというのが出てくるようですね。
+後はマニュアルを読めばこの記事より正しい記述があるはずです。
+
+chkconfigやsysv-rc-conf等でCeleryを止めてSupervisorが起動する点は確認しときます。
+
+# systemdな世界ならそれに従います。
+
+以上なのです。
+
+# コメント等いただければ、説明が足りないところを後で追加するやも。
+# 間違っていたら毎度のごとくご連絡ください。