正在进入ing...

Django+Celery+Redis+flower 整合搭建异步邮件系统

发布时间:2021-02-24 浏览量: 194 文章分类: python

基础版本

为了方便使用我并没有使用最新的Celery,同时查看Celery的官网,已经支持了Django,也就是说可以不需要第三方库就能直接使用。所以也不需要安装什么django-celery那些了。

python==3.8.1
Django==3.0.4  # 理论使用最新的都是可以的,只要你的版本大于1.8即可
celery==4.4.2
celery-with-redis==3.0
flower==0.9.7

实现的效果

1、当访问站点的指定页面时候,可以收到类似邮件通知 Django邮件通知效果

2、整合flower,对开启的异步情况进行监控 django+flower

django+flower详情

3、站点后台增加了访问记录 django后台的访问记录

准备步骤

创建项目、安装redis、等等我这里就跳过了。

项目目录结构

├── db.sqlite3
├── manage.py
├── pein_demo
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-38.pyc
│   │   ├── celery.cpython-38.pyc
│   │   ├── settings.cpython-38.pyc
│   │   ├── urls.cpython-38.pyc
│   │   └── wsgi.cpython-38.pyc
│   ├── asgi.py
│   ├── celery.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── web
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-38.pyc
│   │   ├── admin.cpython-38.pyc
│   │   ├── models.cpython-38.pyc
│   │   ├── tasks.cpython-38.pyc
│   │   └── urls.cpython-38.pyc
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── __init__.py
│   │   └── __pycache__
│   │       ├── 0001_initial.cpython-38.pyc
│   │       └── __init__.cpython-38.pyc
│   ├── models
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   │   ├── __init__.cpython-38.pyc
│   │   │   └── website_models.cpython-38.pyc
│   │   └── website_models.py
│   ├── tasks.py
│   ├── templates
│   ├── tests.py
│   ├── urls.py
│   └── views
│       ├── __pycache__
│       │   └── index_views.cpython-38.pyc
│       └── index_views.py

创建celery.py文件

根据官方的最新文档,其实是不需要在安装别的。所以只要根据官方的教程来基本都没问题

# celery.py
import os

from celery import Celery

# 这里需要注意修改一下项目的名称
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pein_demo.settings')

app = Celery('proj')

app.config_from_object('django.conf:settings', namespace='CELERY')

app.autodiscover_tasks()


@app.task(bind=True)
def debug_task(self):
    print(f'Request: {self.request!r}')
# __init__.py 需要新增
# Django starts so that shared_task will use this app.
from .celery import app as celery_app

__all__ = ('celery_app',)

配置settings.py

# 邮件配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS = False
EMAIL_USE_SSL = True
EMAIL_HOST = 'smtp.qq.com'  # 如果是 163 改成 smtp.163.com
EMAIL_PORT = 465
EMAIL_HOST_USER = '280435089@qq.com' # 帐号
EMAIL_HOST_PASSWORD = 'xxx'  # 密码
DEFAULT_FROM_EMAIL = '佩恩的博客<280435089@qq.com>'


# Celery 配置
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/1'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_RESULT_SERIALIZER = 'json'
CELERTY_TASK_SERIALIZER = 'json'
CELERY_TIMEZONE = "Asia/Shanghai"
CELERYD_MAX_TASKS_PER_CHILD = 10
CELERYD_LOG_FILE = os.path.join(BASE_DIR,'logs','celery_work.log')
CELERYBEAT_LOG_FILE = os.path.join(BASE_DIR,'logs','celery_beat.log')

创建 记录models

# website_models.py

class WebVisitmodels(models.Model):
    ip = models.GenericIPAddressField(verbose_name='ip地址')
    create_time = models.DateTimeField(verbose_name='访问时间', auto_now_add=True)
    path = models.CharField(max_length=180,verbose_name='访问路径',null=True,blank=True)
    def __str__(self):
        return self.ip
    class Meta:
        verbose_name = '访问记录'

创建异步文件

# tasks.py

from __future__ import absolute_import,unicode_literals

from celery import shared_task # 这是异步方法

from django.core.mail import send_mail
from django.conf import settings
from web.models import website_models
import time

@shared_task
def send_to_mail(ip,path):

    localtime = time.asctime( time.localtime(time.time()) )
    mail_title = '站点访问通知'
    mail_content = f'{localtime}收到一条访问记录、ip:{ip}'
    mail_name = settings.DEFAULT_FROM_EMAIL

    visit_obj = website_models.WebVisitmodels.objects.create(
        ip=ip,
        path=path
    )
    visit_obj.save()


    result = send_mail(mail_title, mail_content, mail_name,
        ['280435089@qq.com'], fail_silently=False)

启动

完成上面这些具体逻辑的编写,现在就基本差不多了 启动django python manage.py runserver 启动celery celery -A pein_demo worker -l INFO 启动flower celery -A tasks flower --borker=redis://127.0.0.1

大功告成。。