網站首頁 編程語言 正文
Celery是Python開發分布式任務列隊的處理庫。可以異步分布式地異步處理任務,也可定時執行任務等等。
通常我們可以使用celery在Django執行一些比較耗時的任務(例如發郵件)和后臺任務(例如爬蟲和更新服務器緩存)。
在Django中使用有兩種方式:
- 1)使用django-celery應用
- 2)直接使用Celery
1、Celery方式的選擇
這里Celery的中間人,采用Redis。也可以用Django自身的mongodb等。Celery的中間人你可以理解為在Celery執行過程中的數據支持。保存列隊記錄、執行記錄等等。
需要安裝celery-with-redis,執行命令
pip?install?celery-with-redis
該命令會自動安裝redis(python庫操作redis的庫)、celery、kombu、billiard、amqp、vine和celery-with-redis相關庫。
注意,這里pip安裝的redis是python操作redis的庫,非redis數據庫。
redis數據庫需要獨立安裝,在cmd里輸入?pip3 install redis
先說說django-celery的方式吧。這種方式就是通過manage.py啟動celery。通常先被提到的方案是不會采用。用pip安裝django-celery,在settings引用djcelery應用。
再更新數據庫:
python manage.py makemigrations djcelery
python manage.py migrate djcelery
查看數據庫,會發現多了很多相關的表,顯得十分多余了就。
djcelery還有個用途是在admin后臺動態添加定時任務。這個功能也是比較雞肋,維護不方便而且可能造成各種不可預知的問題。
所以建議直接使用Celery管理Django中的任務(第二種方式)。這種方式也是Celery官網推薦的方式。
2、Django簡單項目準備
這里我也簡單做一個示例。
首先,確保celery和redis已經安裝好了,并且已經啟動了Redis服務。
另外,有個已經搭建好了Django項目。
作為示例,簡單project和簡單app如下:
左邊側邊欄是該django的目錄結構,右邊是myapp中的Blog模型。
再進入后臺隨便加了兩條數據:
為了測試,一切從簡。views.py寫了一個響應方法:
#views.py
from django.shortcuts import render
from django.http import HttpResponse
from models import Blog
import json
def home(request):
data = list(Blog.objects.values('caption'))
return HttpResponse(json.dumps(data), content_type = 'application/json')
django項目的urls.py加了一條首頁的url路由設置:
#urls.py
from django.conf.urls import url
from django.contrib import admin
from myapp.
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', 'myapp.views.home', name='home')
]
運行django項目:
python?manage.py?runserver
打開http://localhost:8000/,如下效果:
3、Django加入Celery
現打開首頁要執行一個收集訪客數據,發送郵件等操作。這是一個耗時任務,若放在home處理方法中執行,用戶打開首頁會很慢。用戶體驗不好,很可能不會等到頁面打開。
通常這個耗時任務可以多線程處理或者異步處理。我們模擬一個耗時任務,丟給Celery異步處理。
先模擬耗時任務,打開views.py,修改如下:
#views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import Blog
import json
import time
def sendmail(email):
print('start send email to %s' % email)
time.sleep(5) #休息5秒
print('success')
return True
def home(request):
#耗時任務,發送郵件
sendmail('test@test.com')
#其他行為
data = list(Blog.objects.values('caption'))
return HttpResponse(json.dumps(data), content_type = 'application/json')
如此一來,至少需要再多等待5秒,才可以打開網頁。
打開settings.py所在的文件夾,新建celery.py文件。
加入如下代碼(注意,因為celery-with-django版本限制,我安裝的celery版本為3.1.25。可能celery4.x的版本代碼不同):
#celery.py
from __future__ import absolute_import, unicode_literals
from celery import Celery
from django.conf import settings
import os
#獲取當前文件夾名,即為該Django的項目名
project_name = os.path.split(os.path.abspath('.'))[-1]
project_settings = '{}.settings'.format(project_name)
#設置環境變量
os.environ.setdefault('DJANGO_SETTINGS_MODULE', project_settings)
#實例化Celery
app = Celery(project_name)
#使用django的settings文件配置celery
app.config_from_object('django.conf:settings')
#Celery加載所有注冊的應用
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
這個文件還沒被加載,接著打開settings.py同個目錄下的__init__.py文件。讓運行該Django項目的時候,加載該文件配置Celery。
修改代碼如下:
#__init__.py
from __future__ import absolute_import, unicode_literals
#引入celery實例對象
from .celery import app as celery_app
還需在settings.py中設置celery,尤其是中間人的設置。若不設置中間人,會提示無法連接中間人的錯誤。
在settings.py文件中添加如下設置:
#celery settings
#celery中間人 redis://redis服務所在的ip地址:端口/數據庫號
BROKER_URL = 'redis://localhost:6379/0'
#celery結果返回,可用于跟蹤結果
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
#celery內容等消息的格式設置
CELERY_ACCEPT_CONTENT = ['application/json',]
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
#celery時區設置,使用settings中TIME_ZONE同樣的時區
CELERY_TIMEZONE = TIME_ZONE
4、把耗時任務丟給celery處理
上面views.py中有個耗時任務sendmail。在myapp應用中新建文件tasks.py,將sendmail方法剪切到該文件中并用定義為celery任務。
tasks.py文件如下代碼:
#tasks.py
from celery.decorators import task
import time
@task
def sendmail(email):
print('start send email to %s' % email)
time.sleep(5) #休息5秒
print('success')
return True
在原有的方法上加上celery裝飾器task(或者也可以通過前面添加的celery_app給sendmail方法加裝飾器):
#tasks.py
#myproject是當前django的項目名
from myproject import celery_app
import time
@celery_app.task
def sendmail(email):
print('start send email to %s' % email)
time.sleep(5) #休息5秒
print('success')
return True
另外原先的views.py修改如下:
#views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import Blog
from .tasks import sendmail #引用tasks.py文件的中sendmail方法
import json
def home(request):
#耗時任務,發送郵件(用delay執行方法)
sendmail.delay('test@test.com')
#其他行為
data = list(Blog.objects.values('caption'))
return HttpResponse(json.dumps(data), content_type = 'application/json')
5、本地啟動celery并測試
啟動celery之前,確保已經安裝redis和啟動redis服務。
本地開發環境運行redis-cli看是否可以正常連接,若不行,再手工執行redis-server命令并保持窗口即可。
接著,啟動celery worker。這個worker是用于異步執行任務的“工作者”。
進入manage.py文件所在的目錄,執行如下命令:
Celery?-A?myproject?worker?-l?info
出現如下窗口和消息,則正常執行。
celery worker會掃描django項目中有哪些task任務,并加入進來。見上圖的藍色字下[tasks]字樣。
最后,再啟動django服務器。這個大家熟悉的python manage.py runserver。
打開首頁,可以發現沒有5秒等待立即得到首頁內容。查看celery worker,可看到執行sendmail方法的消息。
總結
原文鏈接:https://blog.csdn.net/qq_42415326/article/details/95606077
相關推薦
- 2022-11-02 Python封裝解構以及丟棄變量_python
- 2022-07-15 go學習筆記讀取consul配置文件詳解_Golang
- 2022-03-28 用python實現九九乘法表實例_python
- 2022-08-03 Go?GORM版本2.0新特性介紹_Golang
- 2022-12-29 淺析Python是如何實現集合的_python
- 2022-04-10 C#實現計算器功能_C#教程
- 2022-10-28 Django執行python?manage.py?makemigrations報錯的解決方案分享_p
- 2022-07-27 Python中的數據可視化matplotlib與繪圖庫模塊_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支