知乎文章:
Celery 快速入門
某博客:
Celery 快速入門
周期任務(wù)
celery 分布式廣播通知
class based celery tasks
celery 官方總結(jié)的常見問題
celery有什么難理解的
記一次 celery 中的內(nèi)存泄露問題
自己的要求:必須精通celery 因為自已要用到( tm 在其他應(yīng)用里面 的 tasks 文件里面 @share_task 還是沒試成功, 老是報錯, 文章后面會提一下)
其實用 @app.task 吧,能解決大部分任務(wù)了,share_task 的在找一下原因
簡介:
Celery是一個簡單,靈活且可靠的分布式系統(tǒng),可以處理大量消息,同時為操作提供維護該系統(tǒng)所需的工具。
這是一個任務(wù)隊列,著重于實時處理,同時還支持任務(wù)調(diào)度
安裝redis的celery:
pip install -U "celery[redis]"
創(chuàng)建任務(wù)實例:
from celery import Celery
app = Celery('tasks', broker='redis://localhost:6379/0')
# broker 是你redis 的地址,默認使用 0 數(shù)據(jù)庫
@app.task
def send_mail(email):
print("send mail to ", email)
import time
time.sleep(5)
return "success"
# 函數(shù)用app.task 裝飾器修飾之后,就會成為Celery中的一個Task。
啟動任務(wù):
先啟動redis-server:
redis-server.exe
進入redis 安裝目錄寫,或者配置好全局變量后直接寫
運行一個任務(wù):
最好是進入模塊所在的目錄運行 其中tasks 是模塊名字
celery -A tasks worker --loglevel=info
要調(diào)用我們的任務(wù),您可以使用[delay()
]
新啟動命令窗口,進到模塊目錄 :
from 模塊 import 任務(wù)函數(shù)
運行 funcname.delay([args..])
結(jié)果如下圖
調(diào)用周期任務(wù),必須先添加完整的定時表:
from celery import Celery
from celery.schedules import crontab
app = Celery()
@app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
# Calls test('hello') every 10 seconds.
sender.add_periodic_task(10.0, test.s('hello'), name='add every 10')
# Calls test('world') every 30 seconds
sender.add_periodic_task(30.0, test.s('world'), expires=10)
# Executes every Monday morning at 7:30 a.m.
sender.add_periodic_task(
crontab(hour=7, minute=30, day_of_week=1),
test.s('Happy Mondays!'),
)
@app.task
def test(arg):
print(arg)
或者手動:
app.conf.beat_schedule = {
'add-every-30-seconds': {
'task': 'tasks.add',
'schedule': 30.0,
'args': (16, 16)
},
}
app.conf.timezone = 'UTC'
啟動周期任務(wù):
celery -A tests beat
啟動worker 節(jié)點,運行任務(wù):
celery -A tests worker
上面的tests 都是寫任務(wù)那個模塊的名字
結(jié)果:
目錄下 celery 的任務(wù)運行
[django 中使用celery]%E5%8A%A1/)
我們項目大致使用celery 的思路:
pip install django_celery_beat
并且 注冊到 app :
django_celery_beat,
settings.py
# CELERY_RESULT_BACKEND = 'django-db'
CELERY_TIMEZONE = 'Asia/Shanghai'
CELERY_ENABLE_UTC = False
DJANGO_CELERY_BEAT_TZ_AWARE = False # fix bug https://github.com/celery/django-celery-beat/issues/109
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERYD_MAX_TASKS_PER_CHILD = 10
celery.py:
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ops.settings')
app = Celery('ops',
broker=broker)
app.config_from_object('django.conf:settings', namespace='CELERY')
# 然后 就是settings 里面那些 配置了
# 最后來一句
# Load task modules from all registered Django app configs.
app.autodiscover_tasks()
關(guān)于 share_task 和 task 的區(qū)別
簡單說就是 share_task 不需要綁定到具體的 celery app 實例, >@shared_task將為每個應(yīng)用程序創(chuàng)建任務(wù)的獨立實例,從而使任務(wù)可重用
這個就是說,你的 任務(wù)和 celery 應(yīng)用是解耦的。大概是這樣,
你的任務(wù)也可以直接在其他項目中使用。和本身dj 項目沒關(guān)系?
原來我 celery 里有個 配置順序?qū)戝e了,看了官方文檔特意強調(diào)了這個。我才認識到這個問題
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'transform_server.settings')
app = Celery('transform_server', broker="redis://:{passwd}@localhost:6379/0".format(passwd=encrypt_passwd)) # 1
app.config_from_object('django.conf:settings', namespace='CELERY') # 2
app.autodiscover_tasks()
os.environ.setdefault 這一句寫在 app 初始化之前。否則 其他的應(yīng)用的 tasks 注冊不了
看 celery 解釋(ps:改了task 的代碼,記得要重啟一下,celery 的服務(wù),不然用的還是老代碼)
在生產(chǎn)環(huán)境 就最好不要使用 celery -A 這種方式了, 因為這個是 開發(fā)調(diào)試用的.
生產(chǎn)推薦使用 supervisor
安裝 :
1 pip install supervisor
參考: https://www.cnblogs.com/debochan/p/10823984.html
2 echo_supervisord_conf > supervisord.conf
3 supervisord.conf 在最后一行添加內(nèi)容:
[program:celery]
#Set full path to celery program if using virtualenv
command=celery -A worker transform_server --loglevel=INFO # -A 在前面 worker 在后面
directory=/usr/src/transform_server
# environment=CELERY_CONFIG_MODULE="celerytask.celeryconfig-dev"
numprocs=1 ;進程數(shù)
autostart=true ;當(dāng)supervisor啟動時,程序?qū)詣訂?autorestart=true ;自動重啟
4 啟動supervisor:
supervisord -c supervisord.conf
5 關(guān)閉supervisord
supervisorctl -c supervisord.conf shutdown
6.重啟supervisord
supervisorctl -c supervisord.conf reload
supervisor 日志配置文件 默認在 /tmp/supervisord.log 目錄
注意 由于celery 啟動 并不是和 服務(wù)一起的,他是兩個進程的服務(wù),所以不要像,用 celery 改變當(dāng)前服務(wù)的內(nèi)存方面的東西,比如我想 直接在任務(wù)函數(shù)里面修改 server 程序的 類屬性,就不會生效的, celery 能做的就是 除了進城之外的,還是哪個話題,進城通信, 而且是不同機器的,只能通過數(shù)據(jù)庫,等持久化的中間層了。或者通過 request 請求。
關(guān)于 request 請求更改服務(wù)進城的屬性,已經(jīng)驗證過了,是會影響當(dāng)前進城的其他地方的是使用