Python--Django:傳送郵箱 | 利用celery進行非同步處理

此時一位小白路過發表於2020-11-28

傳送郵件需要使用到SMTP伺服器在這裡插入圖片描述

·

常用的免費SMTP伺服器有QQ,163,126

這裡以QQ郵箱為例:
1)進入QQ郵箱首頁,點選設定
在這裡插入圖片描述
2)點選smtp服務的開啟按鈕
在這裡插入圖片描述

3)得到授權碼
在這裡插入圖片描述

·

Django中進行郵箱配置

settings.py

#傳送郵件配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.qq.com'
EMAIL_PORT = 25
#傳送郵件的郵箱
EMAIL_HOST_USER = 'xxx@qq.com'
#在郵箱中設定的客戶端授權密碼
EMAIL_HOST_PASSWORD = 'xxxx'
#收件人看到的發件人
EMAIL_FROM = '名字<xxx@qq.com>'

·

在檢視函式中進行操作

from django.core.mail import send_mail

subject = '天天生鮮資訊'  # 郵件主題
message = ''  # 郵件正文,但是無法解析html格式
sender = settings.EMAIL_FROM  # 傳送人的郵箱
recevier = [email]  # 收件人列表
# token為已經加密了的賬戶id
html_message = '<h1>%s歡迎您成為天天生鮮的註冊會員</h1>請點選下面的連結啟用您的帳戶<br/><a href="http://127.0.0.1:8000/user/active/%s">http://127.0.0.1:8000/user/active/%s</a>' % (username, token, token)

# 必須按照該引數的順序去寫,前四個引數缺一不可,html_message是可加的引數(可解析html格式的郵件正文)
send_mail(subject, message, sender, recevier, html_message=html_message)

實驗結果:
在這裡插入圖片描述

·

在開發中,伺服器傳送郵件,在這段時間中伺服器呈現一個阻塞的狀態,也就是等到郵件傳送完畢後,伺服器才會響應瀏覽器,使用者才能繼續瀏覽網頁

在這裡插入圖片描述

·

解決方法:

將耗時的任務放到後臺非同步執行,不影響使用者其他操作。例如上傳,圖形處理等耗時的任務。

我們引入celerycelery除了可以非同步執行任務外,還可以實現定時處理某些任務

·

celery

Celery是一個功能完備即插即用的任務佇列。
它使得我們不需要考慮複雜的問題,使用非常簡單。
celery適用非同步處理問題,當傳送郵件、或者檔案上傳,影像處理等等一些比較耗時的操作,我們可將其非同步執行,這樣使用者不需要等待很久,提高使用者體驗。

特點

● 簡單,易於使用和維護,有豐富的文件
● 高效,單個celery程式每分鐘可以處理數百萬個任務
● 靈活,celery中幾乎每個部分都可以自定義擴充套件
● celery非常易於整合到一些web開發框架中

·

celery的使用模型

在這裡插入圖片描述

任務佇列的中間人可以是:

1. RabbitMQ

RabbitMQ是一個功能完備,穩定的並且易於安裝的broker,是生產環境中最優的選擇。

2. Redis

Redis是一款功能完備的broker可選項,但是存在因意外中斷或者電源故障導致導致資料丟失的情況。

·

在python中使用celery

以Django框架中傳送郵件為例

1)安裝celery

pip install celery

·

2)新建python包(起名celery_task),在包中建立python檔案(起名tasks)

·

3)在tasks檔案中匯入celery包的Celery類,建立一個Celery類的例項物件

# 使用celery

from celery import Celery

# 建立一個Celery類的例項物件
app = Celery('celery_task.tasks', broker='redis://192.168.43.85:6379/1')

注:Celery類需要兩個引數,第一個是 任務發出者所在包,第二個是 任務佇列(中間人)的地址資訊。此時需要在所選定的中間人電腦中啟動redis服務(sudo service redis start)

·

4)建立任務函式,並且通過上一步建立的類物件的task方法對該任務函式進行裝飾

# 使用celery

from celery import Celery
from django.conf import settings
from django.core.mail import send_mail

# 建立一個Celery類的例項物件
app = Celery('celery_task.tasks', broker='redis://192.168.43.85:6379/1')


# 定義任務函式
@app.task
def send_register_email(to_email, username, token):
    """傳送啟用郵件"""

    # 組織郵件資訊
    subject = '天天生鮮資訊'  # 郵件主題
    message = ''  # 郵件正文
    sender = settings.EMAIL_FROM  # 發件人
    receiver = [to_email]  # 收件人列表
    html_message = '<h1>%s歡迎您註冊啟用天天生鮮會員,請點選下面的連結進行會員啟用</h1><br/><a href="http://127.0.0.1/user/active/%s">' \
                   'http://127.0.0.1/user/active/%s</a>' % (username, token, token)
    send_mail(subject, message, sender, receiver, html_message=html_message)

注:這裡用app.task進行裝飾器裝飾是為了給任務函式增加delay()方法,使得可以向任務佇列(中間人)發出任務

·

5)在Django檢視函式中當需要向任務佇列發出任務時,匯入任務函式所在包,呼叫該任務函式的delay()方法

from celery_task.tasks import send_register_email

# 發郵件
send_register_email.delay(email, username, token)

·

6)在任務處理者的電腦上也需要任務發出者的程式碼並且安裝celery。

·

7)在任務處理者copy的專案中如果需要引用Django初始化後的變數(如settings.py檔案中的屬性),則必須先在程式碼中對其進行初始化

celery_task/tasks.py

# 使用celery

from celery import Celery
from django.conf import settings
from django.core.mail import send_mail

# 在任務處理這一端加上,進行Django初始化
import os
import django

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dailyfresh.settings")
django.setup() # 啟動初始化


# 建立一個Celery類的例項物件
app = Celery('celery_task.tasks', broker='redis://192.168.43.85:6379/1')


# 定義任務函式
@app.task
def send_register_email(to_email, username, token):
    """傳送啟用郵件"""

    # 組織郵件資訊
    subject = '天天生鮮資訊'  # 郵件主題
    message = ''  # 郵件正文,但是無法解析html標籤
    sender = settings.EMAIL_FROM  # 發件人
    receiver = [to_email]  # 收件人列表
    html_message = '<h1>%s歡迎您註冊啟用天天生鮮會員,請點選下面的連結進行會員啟用</h1><br/><a href="http://127.0.0.1/user/active/%s">' \
                   'http://127.0.0.1/user/active/%s</a>' % (username, token, token)

    # 必須按照該引數的順序去寫,前四個引數缺一不可,html_message是可加的引數(可解析html格式的郵件正文)
    send_mail(subject, message, sender, receiver, html_message=html_message)

注:Django進行初始化的程式碼在Django專案中的wsgi.py檔案中

·

8)啟動任務處理者,在任務處理者的電腦中進入已經複製好的專案目錄中執行命令:

celery -A celery_task.tasks worker -l info

在這裡插入圖片描述

celery進行處理
在這裡插入圖片描述

·

注:當任務發出者的程式碼改變時,同時也需要改變任務處理者的程式碼

相關文章