django使用celery定時任務,使用redis和supervisor。
前言
在django專案中,使用celery非同步執行任務,以及建立定時任務。
使用redis作為中介軟體,用supervisor管理程序。
Begin
當前路徑
建立虛擬環境
virtualenv win
進入虛擬環境
source win/bin/activate
安裝package
pip install -r requirements.txt
#檔案requirements.txt的內容
amqp==2.1.4
beautifulsoup4==4.5.3
billiard==3.5.0.2
celery==4.0.2
Django ==1.10.6
kombu==4.0.2
lxml==3.7.3
pytz==2016.10
redis==2.10.5
requests==2.13.0
vine==1.1.3
建立django專案和應用
django-admin startproject pro
cd pro/
django-admin startapp wechat
當前目錄結構
配置django
vi pro/settings.py
INSTALLED_APPS中新增新增的app
在檔案末尾新增celery配置
CELERYD_LOG_FILE
是celery worker的日誌檔案
CELERYBEAT_LOG_FILE
2017年3月20日更新
今天進行資料遷移時發現個問題,一直沒有celery日誌檔案。
後來才發現,原來CELERYD_LOG_FILE
和CELERYBEAT_LOG_FILE
已經在4.0版本中不再支援了。改用引數-f
指定日誌檔案。
建立init_celery.py
vi pro/init_celery.py
修改init.py
為了確保在django啟動時載入了celery應用,修改init.py檔案
vi pro/__init__.py
2017年10月2日增加
將下圖中第5行的from .celery import … 改為 from .init_celery import …
當前目錄結構
測試celery
在redis服務啟動的情況下,測試celery worker已經準備好接收django的任務
celery worker -A pro -l info
使用Ctrl+c關閉,然後再測試celery beat是否已經準備好。
celery beat -A pro -l info
測試通過,說明django專案已經配置好了celery。
做好django專案的準備工作
接下來,我們在wechat的檢視中,簡單的寫一個業務邏輯,在使用者訪問時,及時返回給使用者。
當前的業務場景是:訪問192.168.139.129:7777/money/
時,顯示使用者wangteng的賬戶餘額。
描述待實現功能
希望實現的功能是:
1:當訪問192.168.139.127:7777/money/後,系統訪問http://www.500.com/pages/info/zhongjiang/網站,獲取一等獎每注獎金金額。10秒鐘後,訪問http://www.500.com/pages/info/zhongjiang/dlt.php,獲取二等獎每注獎金金額。將這兩個數相加,存入資料庫,儲存為使用者wangteng的餘額。(該值沒有任何實際意義,只是想建立一個很費時的任務。)
2:每兩分鐘,列印一次當前時間(模擬定時任務)
建立tasks.py
先在wechat下建立檔案tasks.py
,實現該功能。
vi wechat/tasks.py
在檢視views.py中呼叫tasks.py中的任務時,需要使用task_name.delay(args)
的方式。
參考文件
使用supervisor
使用supervisor管理celery worker程式。
sudo vi /etc/supervisord.conf
注意:上面截圖中,對redis的設定有誤。
command=/etc/redis/redis_init_script start
不可以使用上面這種方式啟動redis程序,用這種方式,supervisor監控的是指令碼redis_init_script,而不是redis應該使用下面這個命令啟動redis
command=/usr/local/bin/redis-server /etc/redis/6379.conf
啟動celery worker
時的引數說明
Options:
-A APP, --app=APP app instance to use (e.g. module.attr_name)
-b BROKER, --broker=BROKER
url to broker. default is 'amqp://[email protected]//'
--loader=LOADER name of custom loader class to use.
--config=CONFIG Name of the configuration module
--workdir=WORKING_DIRECTORY
Optional directory to change to after detaching.
-C, --no-color
-q, --quiet
-c CONCURRENCY, --concurrency=CONCURRENCY #worker的程序數,預設是CPU數量
Number of child processes processing the queue. The
default is the number of CPUs available on your
system.
-P POOL_CLS, --pool=POOL_CLS
Pool implementation: prefork (default), eventlet,
gevent, solo or threads.
--purge, --discard Purges all waiting tasks before the daemon is started.
**WARNING**: This is unrecoverable, and the tasks will
be deleted from the messaging server.
-l LOGLEVEL, --loglevel=LOGLEVEL
Logging level, choose between DEBUG, INFO, WARNING,
ERROR, CRITICAL, or FATAL.
-n HOSTNAME, --hostname=HOSTNAME
Set custom hostname, e.g. 'w1.%h'. Expands: %h
(hostname), %n (name) and %d, (domain).
-B, --beat Also run the celery beat periodic task scheduler.
Please note that there must only be one instance of
this service.
-s SCHEDULE_FILENAME, --schedule=SCHEDULE_FILENAME
Path to the schedule database if running with the -B
option. Defaults to celerybeat-schedule. The extension
".db" may be appended to the filename. Apply
optimization profile. Supported: default, fair
--scheduler=SCHEDULER_CLS
Scheduler class to use. Default is
celery.beat.PersistentScheduler
-S STATE_DB, --statedb=STATE_DB
Path to the state database. The extension '.db' may be
appended to the filename. Default: None
-E, --events Send events that can be captured by monitors like
celery events, celerymon, and others.
--time-limit=TASK_TIME_LIMIT
Enables a hard time limit (in seconds int/float) for
tasks.
--soft-time-limit=TASK_SOFT_TIME_LIMIT
Enables a soft time limit (in seconds int/float) for
tasks.
--maxtasksperchild=MAX_TASKS_PER_CHILD
Maximum number of tasks a pool worker can execute
before it's terminated and replaced by a new worker.
-Q QUEUES, --queues=QUEUES
List of queues to enable for this worker, separated by
comma. By default all configured queues are enabled.
Example: -Q video,image
-X EXCLUDE_QUEUES, --exclude-queues=EXCLUDE_QUEUES
-I INCLUDE, --include=INCLUDE
Comma separated list of additional modules to import.
Example: -I foo.tasks,bar.tasks
--autoscale=AUTOSCALE
Enable autoscaling by providing max_concurrency,
min_concurrency. Example:: --autoscale=10,3 (always
keep 3 processes, but grow to 10 if necessary)
--autoreload Enable autoreloading.
--no-execv Don't do execv after multiprocessing child fork.
--without-gossip Do not subscribe to other workers events.
--without-mingle Do not synchronize with other workers at startup.
--without-heartbeat Do not send event heartbeats.
--heartbeat-interval=HEARTBEAT_INTERVAL
Interval in seconds at which to send worker heartbeat
-O OPTIMIZATION
-D, --detach
-f LOGFILE, --logfile=LOGFILE
Path to log file. If no logfile is specified, stderr
is used.
--pidfile=PIDFILE Optional file used to store the process pid. The
program will not start if this file already exists and
the pid is still alive.
--uid=UID User id, or user name of the user to run as after
detaching.
--gid=GID Group id, or group name of the main group to change to
after detaching.
--umask=UMASK Effective umask (in octal) of the process after
detaching. Inherits the umask of the parent process
by default.
--executable=EXECUTABLE
Executable to use for the detached process.
--version show program's version number and exit
-h, --help show this help message and exit
啟動celerybeat
時的引數說明
在檢視這個說明的時候,才發現
celerybeat
已經不建議使用了。應該使用celery beat
(中間有個空格)
Usage: celery beat [options]
Start the beat periodic task scheduler.
Examples::
celery beat -l info
celery beat -s /var/run/celery/beat-schedule --detach
celery beat -S djcelery.schedulers.DatabaseScheduler
Options:
-A APP, --app=APP app instance to use (e.g. module.attr_name)
-b BROKER, --broker=BROKER
url to broker. default is 'amqp://[email protected]//'
--loader=LOADER name of custom loader class to use.
--config=CONFIG Name of the configuration module
--workdir=WORKING_DIRECTORY
Optional directory to change to after detaching.
-C, --no-color
-q, --quiet
--detach
-s SCHEDULE, --schedule=SCHEDULE
--max-interval=MAX_INTERVAL
-S SCHEDULER_CLS, --scheduler=SCHEDULER_CLS
-l LOGLEVEL, --loglevel=LOGLEVEL
-f LOGFILE, --logfile=LOGFILE
Path to log file. If no logfile is specified, stderr
is used.
--pidfile=PIDFILE Optional file used to store the process pid. The
program will not start if this file already exists and
the pid is still alive.
--uid=UID User id, or user name of the user to run as after
detaching.
--gid=GID Group id, or group name of the main group to change to
after detaching.
--umask=UMASK Effective umask (in octal) of the process after
detaching. Inherits the umask of the parent process
by default.
--executable=EXECUTABLE
Executable to use for the detached process.
--version show program's version number and exit
-h, --help show this help message and exit
建立日誌檔案
這兩個日誌檔案,是supervisor的在執行命令期間,螢幕輸出的日誌。並非celery worker和celery beat的日誌。
touch /var/log/supervisor/procelery.log /var/log/supervisor/procelerybeat.log
重啟supervisor
sudo supervisorctl update
執行django專案
python manage.py runserver 0.0.0.0:7777
在瀏覽器輸入192.168.139.129:7777/money/
,瀏覽器能夠立馬接收到django返回的資料,並不需要等待。
檢視celery日誌
檢視celery beat和celery worker的日誌
celery beat的作用,就是按照規定的時間,將“開始執行任務”的指令傳送給celery worker。因此,該日誌檔案中,記錄的是派送任務的時間以及接受任務的任務名稱。
celery0.log日誌檔案中,記錄的是celery層面的資訊,包括任務的執行時間、結束時間、所用時長、返回值等資訊。
celery1.log日誌檔案中,記錄的是task任務過程中的資訊,包括執行過程中,時間時間、輸出的print和info、任務名稱等資訊。
這個檔名中的數字1
表示第幾個worker程序。還記得才supervisord.conf中啟動celery worker時的引數-c嗎?如果啟動worker時,引數-c 3
,那麼這裡將會有celery1.log
、celery2.log
和celery3.log
三個檔案。
這個日誌檔名的定義,是在settings.py
中設定的。
檢視redis
在日誌中,有一串不規則的字串,這個是每個任務的id。可以通過這個id,在redis中查詢到該任務的資訊。
例如查詢任務id為1b68e5cb-21e1-4cdc-9cf6-bdbbfe7785b6
任務的資訊。
redis-cli