celery 學習筆記定時任務和異步任務

1、Celery加入異步和定時任務

Celery除了可以異步執行任務之外,還可以定時執行任務。在實例代碼的基礎上寫個測試方法:

import datetime
import timefrom celery import shared_task
from celery.schedules import crontab
from celery.task import periodic_taskfrom FruitGP2.utils import send_active_email@shared_task
def send_activate_email_async(username,to_email):send_active_email(username,to_email)@periodic_task(run_every=datetime.timedelta(hours=1, minutes=15, seconds=40))
@periodic_task(run_every=10)
def some_task():print('periodic task test!!!!!')# celery -A FruitShopGP2  beat -l info
# celery -A FruitShopGP2  worker -l info# @periodic_task(run_every=crontab())
# def some_task():
#      print('periodic task test!!!!!')
#      print('success')

settings.py

# Celery settingsCELERY_BROKER_URL = 'redis://:@localhost:6379/0'#: Only add pickle to this list if your broker is secured
#: from unwanted access (see userguide/security.html)
CELERY_ACCEPT_CONTENT = ['json']
# CELERY_RESULT_BACKEND = 'db+sqlite:///results.sqlite'
CELERY_RESULT_BACKEND = 'django-db'
CELERY_TASK_SERIALIZER = 'json'

celery.py

from __future__ import absolute_import, unicode_literalsimport osfrom celery import Celery# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'FruitShopGP2.settings')app = Celery('FruitShopGP2')# 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 registered Django app configs.
app.autodiscover_tasks()@app.task(bind=True)
def debug_task(self):print('Request: {0!r}'.format(self.request))

?

該代碼是每分鐘執行一次some_task方法。

啟動celery是使用worker。但worker不能啟動定時任務。啟動方式如下:

1)先確保中間人是否打開,我使用redis作為中間人。可參考

http://docs.celeryproject.org/en/master/getting-started/first-steps-with-celery.html#redis

https://github.com/celery/celery/blob/master/examples/django/proj/settings.py

2)進入django項目的根目錄執行如下代碼啟動celery的worker:

 celery -A FruitShopGP2 worker -l info

其中,myproject是我的django項目名稱。

當出現celery@xxx ready說明redis啟動成功。

有兩個任務,其中一個myapp.tasks.sendmail添加的異步處理任務。myapp.tasks.some_task是本次的定時任務。

3)同樣在django項目的根目錄下再打開一個命令行界面,執行如下代碼:

? ?celery -A FruitShopGP2? beat -l info

可以稍微等待幾分鐘,多執行幾次任務。如下圖 上面的窗口是beat,下面的窗口是worker。可看到print的信息在worker中輸出。

?

?

我們甚至不用打開Django項目的服務器,就可以執行定時任務。?

下方內容僅供參考:

?

2、Celery定時任務時間設置

若你覺得1分鐘等待時間太長。可以設置為每10秒執行一次定時任務。將上面的periodic_task修改如下:

 @periodic_task(run_every=10)

修改代碼,需要重啟Celery的worker和beat。

這個run_every參數是設置定時任務的時間間隔或執行的時間。該參數設置有3種方式。

1)直接設置秒數

例如剛剛所說的10秒間隔,run_every=10,每10秒執行一次任務。1分鐘即是60秒;1小時即是3600秒。

2)通過datetime設置時間間隔

有時直接設置秒數不方便,需要通過計算得到具體秒數。

例如,1小時15分鐘40秒 = 1*60*60 + 15*60 + 40。這種情況可讀性也不高。

可以采用datetime設置,代碼如下:

1 from celery.decorators import periodic_task
2 import datetime
3 
4 @periodic_task(run_every=datetime.timedelta(hours=1, minutes=15, seconds=40))
5 def some_task():
6 print('periodic task test!!!!!')

代碼可讀性明顯提升,而且設置方便。

但這種不能滿足定時定點的時間設置。假如我想固定每天12點15分的時候,執行一次任務。datetime和直接設置秒數的方式都無法實現。這時得使用第3種方式。

?

3)celery的crontab表達式

crontab是比較完善,且稍微有點復雜(相對前面兩種方式而言)的方式。可以實現我們各種設置時間的需求。

例如,前面給出的代碼:

?

1 #coding:utf-8
2 from celery.task.schedules import crontab 
3 from celery.decorators import periodic_task
4 
5 @periodic_task(run_every=crontab())
6 def some_task():
7 print('periodic task test!!!!!')?

?

表示每分鐘0秒時刻執行一次(后面不提這個0秒,大家都知道就行了,省點口水)。

其中,crontab()實例化的時候沒設置任何參數,都是使用默認值。crontab一共有7個參數,常用有5個參數分別為:

minute:分鐘,范圍0-59;

hour:小時,范圍0-23;

day_of_week:星期幾,范圍0-6。以星期天為開始,即0為星期天。這個星期幾還可以使用英文縮寫表示,例如“sun”表示星期天;

day_of_month:每月第幾號,范圍1-31;

month_of_year:月份,范圍1-12。

?

a、默認參數

這些參數可以設置表達式,表達稍微復雜的設置。默認值都是"*"星號,代表任意時刻。即crontab()相當與:

1 crontab(minute='*', hour='*', day_of_week='*', day_of_month='*', month_of_year='*')

含義是每天、每小時、每分鐘執行一次任務。這說法太反人類語言習慣,簡單說就是每1分鐘執行一次任務。

?

b、具體某個值

上面提到這些參數的取值范圍。我們可以直接設置某個值。例如:

1 crontab(minute=15)

即每小時的15分時刻執行一次任務。直接指定某個時刻。以此類推可以設置每天0點0分時刻執行任務的設置如下:

1 crontab(minute=0, hour=0)

當然,也可以設置多個值。例如0分和30分執行一次任務:

crontab(minute='0,30')

這里使用字符串,用逗號隔開數值。這里的逗號是表示多個表達式or邏輯關系。

?

c、設置范圍

設置范圍也是設置多個值,例如指定9點到12點每個小時的每分鐘執行任務。

1 crontab(minute='*', hour='9-12')

這里*號是默認值,可以省略如下:

1 crontab(hour='9-12')

上面提到逗號是or邏輯關系。拓展一下,指定9點到12點和20點中每分鐘執行任務:

1 crontab(hour='9-12,20')

crontab的表達式越來越復雜了。celery還提供了一個類得到表達式解析結果,代碼如下:

1 from celery.task.schedules import crontab_parser
2 r = crontab_parser(23, 0).parse('9-12,20')
3 print(r)

其中,crontab_parse是一個解析類。第1個參數是范圍的最大值;第2個參數是范圍的最小值。通過parse輸入表達式,可得到表達式的解析結果:

1 set([9, 10, 11, 12, 20])

下面很多地方我們都可以通過該方法驗證解析結果。

??

d、設置間隔步長

假如我要設置1、3、5、7、9、11月份每天每分鐘執行任務,按照上面的做法可以設置如下:

1 crontab(day_of_month='1,3,5,7,9,11')

觀察數據可以發現,都是間隔2的步長。需要設置的數字比較少,若數字比較多顯得很麻煩。例如我想每間隔2分鐘就執行一次任務,要寫30個數字想想就覺得很麻煩。crontab表達式還提供了間隔的處理,例如:

1 crontab(minute='*/2')
2 crontab(minute='0-59/2') #效果等同上面

這個/號不是除以的意思。相當與range的第3個參數,例如:

1 range(0, 59+1, 2)

差不多crontab表達式就這些,多舉幾個例子:

?

 1 #每2個小時中每分鐘執行1次任務2 crontab(hour='*/2')3 4 #每3個小時的0分時刻執行1次任務5 #即[0,3,6,9,12,15,18,21]點0分6 crontab(minute=0, hour='*/3')7 8 #每3個小時或8點到12點的0分時刻執行1次任務9 #即[0,3,6,9,12,15,18,21]+[8,9,10,11,12]點0分
10 crontab(minute=0, hour='*/3,8-12')
11 
12 #每個季度的第1個月中,每天每分鐘執行1次任務
13 #月份范圍是1-12,每3個月為[1,4,7,10]
14 crontab(month_of_year='*/3')
15 
16 #每月偶數天數的0點0分時刻執行1次任務
17 crontab(minute=0, hour=0, day_of_month='2-31/2')
18 
19 #每年5月11號的0點0分時刻執行1次任務
20 crontab(0, 0, day_of_month='11', month_of_year='5')

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/456244.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/456244.shtml
英文地址,請注明出處:http://en.pswp.cn/news/456244.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

FBV(function base views) 顧名思義基于函數的視圖類 CBV(class base views)基于類的視圖類

一. 概念 FBV(function base views) 顧名思義基于函數的視圖類 CBV(class base views)基于類的視圖類 至于區別呢? 我覺得只是寫法上的不一樣, 實現的結果都是一樣的, 我比較喜歡用CBV模式, 因為在Django中內部幫我做了請求方式…

rpm查詢

rpm -q 的用法:1、 rpm -qa 可以查看所有已經安裝過的rpm包2、rpm -qf 文件名絕對路徑,可以查看該文件由哪個包安裝的3、 rpm -ql 包名,可以查看該包安裝哪些文件4、 rpm -qi 包名,可以查看該包的詳細信息查詢一個包是否安裝命令&…

IntelliJ idea學習資源

工作需要, 最近得從Eclipse轉戰到Idea, 找了些不錯的學習資料: 1, 從eclipse上遷移過來的用戶說明: https://www.jetbrains.com/help/idea/2016.3/eclipse.html 2, 極客學院的idea使用入門教程: http://wiki.jikexueyuan.com/project/intellij-idea-tutorial/project-compositi…

linux下的安裝:openssl

openssl簡介 openssl是一個功能豐富且自包含的開源安全工具箱。它提供的主要功能有:SSL協議實現(包括SSLv2、SSLv3和TLSv1)、大量軟算法(對稱/非對稱/摘要)、大數運算、非對稱算法密鑰生成、ASN.1編解碼庫、證書請求(PKCS10)編解碼、數字證書編解碼、CRL編解碼、OC…

使用WinIO庫實現保護模式下的IO和內存讀寫

問題已解決: 原因是函數的調用方式與WinIO中不一致,使用的時候漏掉了__stdcall。 函數原定義為: 在實際的GPIO讀寫中遇到以下問題: SetPortVal可正常寫入,但是GetPortVal無法讀取,程序崩潰,問題…

php 一些個 常用 函數

urlencode()函數原理就是首先把中文字符轉換為十六進制,然后在每個字符前面加一個標識符%。urldecode()函數與urlencode()函數原理相反,用于解碼已編碼的 URL 字符串,其原理就是把十六進制字符串轉換為中文字符json_decode(json,true); 輸出的…

windows10中遠程訪問憑據不工作

遠程同學電腦,發現輸入賬號密碼還是不行,提示您的憑據不工作,問題解決:WinR---gpedit.msc網絡訪問----經典。轉載于:https://blog.51cto.com/germa66/1934745

pycharm的 crtl + r 使用正則表達式進行 request-header格式更改

pycharm的 crtl r 使用正則表達式進行 request-header格式更改 復制粘貼之前 使用 ‘’‘ ’‘’ 保證格式不亂 改為正確格式

Android(組件大全)

ORM: Android GreenDao sqlite UI: Snackbar是Android支持庫中用于顯示簡單消息并且提供和用戶的一個簡單操作的一種彈出式提醒。當使用Snackbar時,提示會出現在消息最底部,通常含有一段信息和一個可點擊的按鈕。Support Design Library轉載于:https://w…

QT的常用對話框的應用

QMessageBox類提供了常用的彈出式對話框&#xff1a;提示、警告、錯誤、詢問、關于對話框 需要添加頭文件 #include <QMessageBox> MESSAGE 是要是顯示的字符串 void Dialog::criticalMessage() { QMessageBox::StandardButton reply; reply QMessageBox::critical…

【spider】Tesseract機器視覺實現驗證碼識別

本文將重點介紹機器視覺的一個分支&#xff1a;文字識別&#xff0c; 介紹如何用一些 Python庫來識別和使用在線圖片中的文字 我們可以很輕松的閱讀圖片里的文字&#xff0c;但是機器閱讀這些圖片就會非常困難&#xff0c;利用這種人類用戶可以正常讀取但是大多數機器人都沒法…

初識MVC

好多次聽見別人說MVC&#xff0c;那么MVC到底是什么呢&#xff1f;今天來一探到底&#xff0c;揭開其神奇面紗。。 MVC介紹&#xff1a; MVC全名Model View Controller&#xff0c;是模型&#xff08;Model&#xff09;-視圖&#xff08;View&#xff09;-控制器&#xff08;Co…

【spider】selenium模擬點擊斗魚示例

from selenium import webdriver import timeurl https://www.douyu.com/directory/all# 動態html網頁加載可能出現的問題&#xff1a;element is not attached to the page document # 標簽沒有及時的加載顯示出來&#xff0c;如果加載時間不夠&#xff0c;可能報錯 # try e…

webpack簡介

webpack是 前端資源模塊化管理工具和打包工具&#xff1b;webpack本身只能識別模塊引入&#xff0c;打包模塊的功能&#xff1b;webpack能識別ES Moudule、common JS等模塊規范一、現有模塊系統1、CommonJS關鍵詞&#xff1a;module.exports exports require特點&#xf…

【Python + Selenium】之JS定位總結

1、滾動條 driver.set_window_size(500,500) js "window.scrollTo(0,200)" #左&#xff1a;距左邊橫滾、右&#xff1a;距上邊豎滾 driver.execute_script(js) 2、獲取元素的值 button driver.find_element_by_css_selector("#su") #定位按鈕 input…

BigDecimal類整除報錯的解決方案

例如&#xff1a; BigDecimal num1 new BigDecimal("10"); BigDecimal num2 new BigDecimal("3"); BigDecimal num3 num1.divide(num2); 其實devide的函數定義如下 BigDecimal.divide(BigDecimal divisor, int scale, RoundingMode roundingMode) ;…

NodeJS中的require和import

ES6標準發布后&#xff0c;module成為標準&#xff0c;標準的使用是以export指令導出接口&#xff0c;以import引入模塊&#xff0c;但是在我們一貫的node模塊中&#xff0c;我們采用的是CommonJS規范&#xff0c;使用require引入模塊&#xff0c;使用module.exports導出接口。…

【selenium】selenium和requests登陸的區別

requests登陸 import requests import time t int(time.time()*1000) # 創建一個會話 s requests.Session() post_url http://account.chinaunix.net/login/login data {username: xxxxxxxxx,password: xxxxxxxxx,_token: nmSXhgHib8dTIC9DrATSkTzBBo4zz9eqDEPeG5i1,_t: t…

【spider】多線程爬蟲

多線程工作原理 多線程示意圖 Queue&#xff08;隊列對象&#xff09; queue是python中的標準庫&#xff0c;可以直接from queue import Queue引用;隊列是線程間最常用的交換數據的形式 python下多線程的思考 對于資源&#xff0c;加鎖是個重要的環節。Queue&#xff0c;是線…

css設置文字上下居中,一行文字居中,兩行或多行文字同樣居中。

HTML: <div class"book-detail-store-item align-center-vertical">居中文字</div> CSS: .book-detail-store-item {width: 50px&#xff1b;height&#xff1a;50px&#xff1b;line-height: 25px;font-size: 12px;}/*flex垂直居中對齊*/ .align-center…