celery異步發送郵件


利用Django框架發送郵件的詳細過程,在前兩天的博客中有所記錄,但是單純的那樣發郵件是有非常大的問題的,這就需要celery異步發送來解決

 

首先我們來看一下郵件發送的過程:

  • Django網站先發送到smtp服務器
  • smtp服務器再把郵件發送到目的郵箱

這里有兩個不確定時間:

  • Django網站----->smtp服務器
  • smtp服務器----->目的郵箱

這樣的情況下,假定Django網站發送郵件到smtp耗時是5s,那么用戶在表單中輸入信息之后提交,頁面需要刷新5s才會跳轉。顯然,這是我們非常不願意看見的情況,極大的影響了用戶體驗。

利用celery異步發送郵件:

  • 過程圖解:這里我的所有程序都是在一台電腦上

  • 首先在項目虛擬環境里安裝celery模塊: 

  • 然后在Django項目里新建一個python package,名字叫做celery_tasks,里面創建一個python文件tasks.py

    • 首先確保你的電腦上已經安裝有Redis數據庫
    • 在項目的虛擬環境中還需要 pip install redis
    • 在tasks.py中的代碼如下:其中第8-11行,是在使用不同的電腦運行celery的發起者、中間人、中間人時所需要用到的,這里我都是在一台電腦上運行,所以完全可以不寫
       1 # 使用celery
       2 import time
       3 from celery import Celery
       4 from django.conf import settings
       5 from django.core.mail import send_mail
       6 
       7 # 在任務處理者一端加這幾句,如果使用的不是同一台電腦,django環境的初始化,一般啟動項目的一端不需要加
       8 import os
       9 import django
      10 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dailyfresh.settings')
      11 django.setup()
      12 
      13 # 創建一個Celery類的實例對象
      14 app = Celery('celery_tasks.tasks', broker='redis://127.0.0.1:6379/9')
      15 
      16 # 定義任務函數
      17 @app.task()
      18 def send_register_active_mail(to_mail, username, token):
      19     """發送激活郵件"""
      20     # 組織郵件信息
      21     subject = '天天生鮮歡迎信息'
      22     message = ''
      23     sender = settings.EMAIL_FROM
      24     receiver = [to_mail,]
      25     html_message = '<h1>{},歡迎您成為天天生鮮注冊會員</h1>請點擊下面鏈接激活您的用戶<br><a href="http:127.0.0.1:8000/user/active/{}">http:127.0.0.1:8000/user/active/{}</a>'.format(
      26         username, token, token)
      27     send_mail(subject, message, sender, receiver, html_message=html_message)
      28     # 利用time模塊模擬發了五秒鍾郵件,原方法會頁面加載5秒
      29     time.sleep(5)
    • 修改原先視圖函數里發送郵件的部分,修改的部分如下,原先發送郵件的代碼被我們封裝到了tasks.py文件中的send_register_active_mail函數中
       1 # 導入上述創建的tasks.py文件中的異步發送郵件的方法
       2 from celery_tasks.tasks import send_register_active_mail
       3 
       4 # 發郵件
       5 # subject = '天天生鮮歡迎信息'
       6 # message = ''
       7 # sender = settings.EMAIL_FROM
       8 # receiver = [email]
       9 # html_message =  '<h1>{},歡迎您成為天天生鮮注冊會員</h1>請點擊下面鏈接激活您的用戶<br><a href="http:127.0.0.1:8000/user/active/{}">http:127.0.0.1:8000/user/active/{}</a>'.format(username, token, token)
      10 # send_mail(subject, message, sender, receiver, html_message=html_message)
      11 # 上面注釋掉了原先發送郵件的代碼,現在用剛導入的函數所替代
      12 send_register_active_mail.delay(email, username, token)    
  • 現在環境和代碼都已經完成了,接下來在終端運行命

    • celery -A celery_tasks.tasks worker -l info -P eventlet

    • 其中 -P enentlet 是為了防止 win10 運行出錯而附加的
    • 這樣我們就啟動了任務處理者
    • 如果任務處理者和redis都在另一台計算機上,就需要把項目和環境拷貝過去,然后也是同樣的命令啟動,不過在不同的計算機上就一定不能少了tasks.py中的8-11行的內容,因為tasks.py文件中的操作用到了Django項目中的一些配置
  • 此時,在進行注冊操作,雖然我們用 time.sleep函數模擬了郵件發送5s,但是當提交表單的時候發送郵件的操作已經是去異步處理了,頁面幾乎是沒有太多延遲進行了刷新,這里就不再演示了,以下是在進行注冊操作時,終端打印的信息

    • 最下面兩行就是先接收到了發送郵件的請求,然后又執行發送的過程

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM