LoginSignup
10
12

More than 3 years have passed since last update.

CeleryをDjangoで動かす

Posted at

やったこと

Django・Celeryで非同期ジョブ実行の仕組みを実装した

背景

Django上でseleniumを使ってSBI証券の売買注文をする機能を実装したので、それをSlackからinteractiveコマンドを利用して実行させたくなった。

しかしslackのinteractiveコマンドでは3秒以内にレスポンスを返さないとエラーとなる仕様のため、時間がかかる作業はレスポンスだけ返して非同期で実行する必要があった。

そこでceleryを利用して、djangoで非同期ジョブを実行できるようにした。

環境

ubuntu 16.04
Python 3.5.2
Django 1.11.7

導入手順

1. redis導入

celeryでメッセージブローカとして利用するredisをサーバにインストールする

下記URLに従って実行
https://weblabo.oscasierra.net/redis-ubuntu1604-install-apt/

立ち上げも忘れずに

sudo service redis-server start
sudo systemctl enable redis-server

2. celery導入

pipでインストールする

pip install celery django-celery-results redis django-redis

一緒にインストールしたdjango-celery-resultsで非同期ジョブの実行結果をDBに保存できる

settings.py

下記の設定を追記する

settings.py
# CELERY
CELERY_BROKER_URL = "redis://127.0.0.1:6379/1"
CELERY_RESULT_BACKEND = "django-db"

celery.py

settings.pyと同じ階層に新規作成する
environを用いて設定ファイルを使い分けているので、celery.pyでも同じように設定ファイルを読み込む

celery.py
import os
from celery import Celery
import environ
env = environ.Env(DEBUG=(bool, False),)  # set default values and casting
environ.Env.read_env('.env')  # reading .env file

# set the default Django settings module for the 'celery' program.
settings = os.getenv(
   "DJANGO_SETTINGS_MODULE", env("CELERY_ENVIRONMENT"))
os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings)

app = Celery('プロジェクト名')

# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')

# Load task modules from all registere

ジョブ定義

関数にデコレータ@app.task()をつけると、ジョブとして実行できる。
seleniumでのSBI注文の実装は省略する。
下記のようにジョブ定義と実行のファイルを用意すれば良い

job.py
from プロジェクト名.celery import app

@app.task()
def add_numbers(a, b):
    return a+b
execute.py
from xxx.job import add_numbers

def execute()
    add_numbers.delay(10, 3) 

3. celery実行

サービスとして起動しておく

下記のサービスファイルを作成

/etc/systemd/system/celery.service
[Unit]
Description=celery daemon
After=network.target

[Service]
User=furuya
Group=furuya
WorkingDirectory=[DjangoプロジェクトのPATH]
ExecStart=/home/furuya/.local/bin/celery -A プロジェクト名 worker --concurrency=1

[Install]
WantedBy=multi-user.target

下記を実行

sudo systemctl daemon-reload
sudo service celery start
sudo systemctl enable celery

celeryが動いていれば、非同期ジョブは順次実行されていく

4. 実行結果の確認

DjangoのAdmin画面で、実行結果を確認できる

スクリーンショット 2019-05-05 16.07.01.png

各レコードへのリンク先で、パラメータ等の詳細も確認可能

10
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
12