DockerとDjangoとceleryでタスクの非同期処理

先日、Pythonとceleryを使った非同期通信の勉強をしました。

今日は、Docker + Django + celeryでタスクの非同期処理について、勉強しようと思います。

前提条件

  • Mac 環境で動作確認
  • Dockerおよびdocker-composeがインストールされていること

事前準備

以下のフォルダとファイルを用意してください。

Django + Redis + Postgres環境の構築

Dockerを使って、Django + Redis + Postgresの環境を構築します。

尚、celeryを使うには、Redisが必要です。

まずは、docker-compose.ymlの設定です。

次にDockerfileの設定をしましょう。

Makefileには、Dockerを操作するコマンドを書きます。

requirements.txtにインストールしたいモジュールを書きます。

ここまでで、一旦ビルドします。

Django のプロジェクトを作成します。

以下のコマンドで、Djangoを起動してみましょう。

ブラウザから「localhost:8000」にアクセスしてみましょう。

続いて、PostgresとredisをDjangoで使えるようにするために設定を変更します。今は、下記のフォルダ構成になっていると思います。

settings.pyを変更します。

まずは、DBをデフォルトのSQLite3からPostgresに変更する設定です。

次に、redisの設定をします。

LOCATIONのredisは、docker-compose.ymlに指定したサービス名(redis)です。こうしないと通信ができません。

一度、Ctrl+cでdockerを止めて、再度コンテナを立ち上げてください。

Postgresでマイグレーションが走りましたね。

redisが使えるようになっているか、確認してみましょう。

redisに入れたデータを取得することができました。OKですね。

Celeryの組み込み

前置き(環境構築)が長ったのですが、ようやく本題に入ります。

公式ドキュメントを参考にCeleryを組み込んでいきましょう。

公式ドキュメントによると、プロジェクト(ここでは、app/app)配下にcelery.pyを作れとのこと。

このファイルに以下の記述をします。

ほとんど、公式からの流用です。変更1,2の場所だけ、自分のプロジェクトに合わせて変更してます。

それから、app/app/__init__.pyに以下の追記をしましょう。

Django起動時に、@shared_taskでデコレートされたtaskを読み込むことを保証するそうです。

app.autodiscover_tasks()は、プロジェクト全体で、tasks.pyを発見してくれる便利ツールだそうです。tasks.pyにしないといけないルールなのは、少し不便そうですね。

アプリケーションを作成しましょう。

settings.pyにこのdemoappを登録します。また、celeryがredisを使用する設定を入れておきましょう。

先ほど作成したtasks.pyに以下の実装をします。

次にview.pyにこのタスクを使う設定を追加しましょう。

appプロジェクト配下のurls.pyを以下のように変更しましょう。

そして、docker-compose.ymlに以下のceleryコンテナを追加してください。

celeryコンテナを追加しました。

celery -A app worker -l infoは、celeryのワーカープロセスを開始します。

コンテナを立ち上げて、「localhost:8000」にアクセスし、コンソールを確認してみましょう。

task_idが返却されているので、celeryにタスクが渡されていることはわかります。

celeryコンテナを別途作成したのは、Djangoの「python manage.py runserver」とceleryの「celery -A app worker -l info」を別プロセスで扱いたかったからです。

コンテナを分けたのにも関わらず、taskが実行できていますよね?

まだ詳しく調べられた訳ではないのですが、以下のようになっているのだと思います。

  1. Django上でタスク実行(views.py)
  2. Redisにタスク登録
  3. celeryプロセスがRedisからタスクを上取り、実行
  4. postgresに実行後のタスクを登録

間違ってたら、ご指摘ください^^; celeryは、初めてなもので。。

管理ユーザーを作成しましょう。Makefileに作成用のコマンドを既に入れています。

http://localhost:8000/admin/django_celery_results/taskresult/」にアクセスすると、実行されたタスクが確認できます。

まとめ

celeryを使うと結構簡単に非同期処理が実装できて良いですね。

コメントを残す