Django+celery+flower
- Django的定時任務及可視化監控
- Django
Django的定時任務及可視化監控
Django的定時任務,以及可視化監控。
Django
- Django;
首先在python中新建虛擬環境并激活
pip install virtualenv
python -m venv venv
source venv/bin/activate
pip install django #安裝django
安裝
- 創建django項目;
django-admin startproject myproject
cd myproject
啟動Django開發服務器:
python manage.py runserver
默認情況下,服務器會運行在 http://127.0.0.1:8000/。
完成后,可以停用虛擬環境:
deactivate
- redis;
這里使用源碼安裝,參考redis官網
新開一個窗口,不在python虛擬環境操作
wget https://download.redis.io/redis-stable.tar.gz
tar -xzvf redis-stable.tar.gz
cd redis-stable
make
sudo yum install openssl-devel
make BUILD_TLS=yes
sudo make install
cp redis.conf /etc/
redis-server /etc/redis.conf
檢查redis是否啟動
redis-cli
127.0.0.1:6379> ping
PONG #成功
- celery簡單示例;
安裝
pip install celery django-celery-beat
新建一個應用
python manage.py startapp myapp
將 myapp 和 django_celery_beat 添加到 INSTALLED_APPS 中,編輯 myproject/settings.py 文件:
INSTALLED_APPS = [...'django_celery_beat','myapp',
]
在 myproject 文件夾下創建一個名為 celery.py 的文件,并添加以下內容:
import os
from celery import Celeryos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
app = Celery('myproject')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
在 myproject/init.py 文件中添加以下內容:
from .celery import app as celery_app__all__ = ('celery_app',)
在 myproject/settings.py 文件中添加 Celery 配置:
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
CELERY_TIMEZONE = "Asia/Shanghai"
CELERY_ENABLE_UTC = False
在 myapp 文件夾下創建一個名為 tasks.py 的文件,并定義一個簡單的定時任務:
from celery import shared_task
import datetime@shared_task
def print_time():now = datetime.datetime.now()print(f"Current time: {now}")
在 myproject/celery.py 文件中定義定時任務的調度計劃:
from celery.schedules import crontabapp.conf.beat_schedule = {'print-time-every-minute': {'task': 'myapp.tasks.print_time','schedule': crontab(minute='*'),},
}
這里定義了一個名為 print-time-every-minute 的定時任務,它會每分鐘執行一次 myapp.tasks.print_time 任務。
啟動 Celery worker:
celery -A myproject worker -l info
啟動 Celery beat:
celery -A myproject beat -l info
啟動 Django 開發服務器:
python manage.py runserver
查看結果
在終端中可以看到 Celery beat 每分鐘調度一次 print_time 任務,并在 Celery worker 的終端中打印當前時間。
- 定時任務時間寫法;
在 Celery 中,定時任務的定時時間可以通過多種方式指定,主要包括以下幾種常見的寫法
1)使用 crontab,例如每分鐘、每小時、每天、每周等
from celery.schedules import crontabapp.conf.beat_schedule = {'print-time-every-minute': {'task': 'myapp.tasks.print_time','schedule': crontab(minute='*'), # 每分鐘執行一次},'print-time-every-hour': {'task': 'myapp.tasks.print_time','schedule': crontab(minute=0, hour='*'), # 每小時的第0分鐘執行一次},'print-time-every-day': {'task': 'myapp.tasks.print_time','schedule': crontab(minute=0, hour=0), # 每天的凌晨0點執行一次},'print-time-every-week': {'task': 'myapp.tasks.print_time','schedule': crontab(minute=0, hour=0, day_of_week=1), # 每周一凌晨0點執行一次},
}
參數說明:
minute:分鐘,范圍是 0-59。
hour:小時,范圍是 0-23。
day_of_week:星期幾,范圍是 0-6,其中 0 表示星期天。
2)使用 timedelta,指定任務的執行間隔,例如每幾秒、幾分鐘、幾小時等。
from datetime import timedeltaapp.conf.beat_schedule = {'print-time-every-10-seconds': {'task': 'myapp.tasks.print_time','schedule': timedelta(seconds=10), # 每10秒執行一次},'print-time-every-15-minutes': {'task': 'myapp.tasks.print_time','schedule': timedelta(minutes=15), # 每15分鐘執行一次},'print-time-every-2-hours': {'task': 'myapp.tasks.print_time','schedule': timedelta(hours=2), # 每2小時執行一次},
}
3)timedelta 的固定時間間隔,需要任務在固定的時間間隔內執行,可以使用 timedelta 的組合
from datetime import timedeltaapp.conf.beat_schedule = {'print-time-every-1-hour-30-minutes': {'task': 'myapp.tasks.print_time','schedule': timedelta(hours=1, minutes=30), # 每1小時30分鐘執行一次},'print-time-every-2-days-12-hours': {'task': 'myapp.tasks.print_time','schedule': timedelta(days=2, hours=12), # 每2天12小時執行一次},
}
4)crontab 的高級組合,支持更復雜的組合,例如指定特定的分鐘、小時、星期幾等
from celery.schedules import crontabapp.conf.beat_schedule = {'print-time-specific-time': {'task': 'myapp.tasks.print_time','schedule': crontab(minute=30, hour=14, day_of_week='mon,tue,wed'), # 每周一、二、三的下午2點30分執行一次},'print-time-specific-dates': {'task': 'myapp.tasks.print_time','schedule': crontab(minute=0, hour=0, day_of_month='1,15'), # 每月的1號和15號凌晨0點執行一次},
}
參數說明:
minute:可以指定具體的分鐘,例如 30 或 0,15,30,45。
hour:可以指定具體的小時,例如 14 或 0-23。
day_of_week:可以指定具體的星期幾,例如 mon,tue,wed 或 1-5。
day_of_month:可以指定具體的日期,例如 1,15。
5)crontab 的通配符指定更靈活的時間。
from celery.schedules import crontabapp.conf.beat_schedule = {'print-time-every-other-minute': {'task': 'myapp.tasks.print_time','schedule': crontab(minute='*/2'), # 每隔2分鐘執行一次},'print-time-every-other-hour': {'task': 'myapp.tasks.print_time','schedule': crontab(minute=0, hour='*/2'), # 每隔2小時執行一次},'print-time-every-weekday': {'task': 'myapp.tasks.print_time','schedule': crontab(minute=0, hour=0, day_of_week='1-5'), # 每個工作日的凌晨0點執行一次},
}
參數說明:
minute=‘/2’:每隔2分鐘執行一次。
hour='/2’:每隔2小時執行一次。
day_of_week=‘1-5’:表示星期一到星期五。
6)timedelta 的動態間隔,動態調整任務的執行間隔,可以在任務中動態修改 beat_schedule
from datetime import timedelta
from celery import shared_task@shared_task
def dynamic_task():print("Dynamic task executed")# 修改任務的執行間隔app.conf.beat_schedule['dynamic-task']['schedule'] = timedelta(seconds=30)app.conf.beat_schedule = {'dynamic-task': {'task': 'myapp.tasks.dynamic_task','schedule': timedelta(seconds=10), # 初始間隔為10秒},
}
- flower;
安裝flower
pip install flower
啟動,啟動之前確保celery已經配置好并運行正常
celery -A myproject flower --port=5555 --broker=redis://localhost:6379/0
加密啟動
celery -A myproject flower --port=5555 --broker=redis://localhost:6379/0 --basic_auth=user:password
配置celery,在 Celery 配置中啟用事件發送功能,在 myproject/celery.py 文件中添加以下配置:
app.conf.update(worker_send_task_events=True, # 啟用任務事件發送task_send_sent_event=True, # 啟用任務發送事件
)
在瀏覽器中訪問 http://127.0.0.1:5555/,即可看到 Flower 的監控界面