Celery sends activation email asynchronously
Introduction to Celery
- 1.Celery introduction
- Click to view Celery reference documentation
- Celery is a fully functional plug-and-play task queue
- Celery is suitable for asynchronous processing problems, such as sending emails, file uploading, image processing and other time-consuming operations. We can execute them asynchronously, so that users do not need to wait for a long time, improving user experience
- 2.Celery Features:
- Simple, easy to use and maintain, with extensive documentation
- Efficient, a single Celery process can handle millions of tasks per minute
- Flexible, almost every part in Celery can be custom extended
- Celery is very easy to integrate into some web development frameworks
3. Install Celery
# 进入虚拟环境 pip install celery
4.Celery composition structure
- A task queue is a mechanism for working across threads and machines
- The unit of work that contains the task in the task queue. There is a dedicated worker process that continuously monitors the task queue and obtains new tasks from it and processes them
- Celery communicates through messages, usually using a broker (middleman) to coordinate client (task issuer) and worker (task handler)
- The client sends a message to the queue, and the broker dispatches the information in the queue to the worker for processing
- A Celery system can contain many workers and brokers, which can enhance horizontal scalability and high availability performance.
The structure of Celery is an embodiment of the producer-consumer model
Celery uses
1. Create a Celery asynchronous task file
2. Create application object/client/client
- The application object internally encapsulates the tasks to be executed asynchronously
- Celery():
- Parameter 1 is the asynchronous task path
- Parameter 2 is the specified broker
- redis://password@redis ip:port/database
- redis://192.168.243.191:6379/4
- Returns the client application object app
- send_active_email(): Internally encapsulates the content of the activation email and registers it with the decorator @app.task
Call python's send_mail() to send the activation email
from celery import Celery from django.core.mail import send_mail from django.conf import settings # 创建celery应用对象 app = Celery('celery_tasks.tasks', broker='redis://192.168.243.191:6379/4') @app.task def send_active_email(to_email, user_name, token): """发送激活邮件""" subject = "天天生鲜用户激活" # 标题 body = "" # 文本邮件体 sender = settings.EMAIL_FROM # 发件人 receiver = [to_email] # 接收人 html_body = '<h1>尊敬的用户 %s, 感谢您注册天天生鲜!</h1>' \ '<br/><p>请点击此链接激活您的帐号<a href="http://127.0.0.1:8000/users/active/%s">' \ 'http://127.0.0.1:8000/users/active/%s</a></p>' %(user_name, token, token) send_mail(subject, body, sender, receiver, html_message=html_body)
3. Broker
- Example: Redis database as middleman broker is demonstrated here
- Celery needs a way to send and receive messages. We call this middleware for storing messages a message broker, or a message middleman.
As an intermediary, we have several options:
1.RabbitMQ
- RabbitMQ is a full-featured, stable and easy-to-install broker. It is the best choice for production environments.
For details on using RabbitMQ refer to the following link: http://docs.celeryproject.org/en/latest/getting-started/brokers/rabbitmq.html#broker-rabbitmq
If you are using an Ubuntu or Debian distribution of Linux, you can install RabbitMQ directly with the command:
sudo apt-get install rabbitmq-server
- After installation, the RabbitMQ-server server is already running in the background.
- If you are not using Ubuntu or Debian, you can go to the following website: http://www.rabbitmq.com/download.html to find the version software you need.
2. Redis
- Redis is also a full-featured broker option, but it is more likely to lose data due to unexpected outages or power failures.
- Regarding which Redis is used as the Broker, you can visit the following URL: http://docs.celeryproject.org/en/latest/getting-started/brokers/redis.html#broker-redis
4. Create worker
- Example: Here is a demonstration of creating a worker into a ubuntu virtual machine, with ubuntu as the Celery server
Celery server create worker steps
1. Copy the project code to the ubuntu virtual machine
- and add the following code at the top of the celery_tasks/tasks.py file
Role: enable Celery's workers to load the Django configuration environment
import os os.environ["DJANGO_SETTINGS_MODULE"] = "dailyfresh.settings" # 放到Celery服务器上时添加的代码 import django django.setup()
2. The terminal creates a worker
celery -A celery_tasks.tasks worker -l info
3. Open redis-server and view the broker
4. Test sending emails
5. View the asynchronous task messages received by the worker
Complete registration logic implementation code
class RegisterView(View):
"""类视图:处理注册"""
def get(self, request):
"""处理GET请求,返回注册页面"""
return render(request, 'register.html')
def post(self, request):
"""处理POST请求,实现注册逻辑"""
# 获取注册请求参数
user_name = request.POST.get('user_name')
password = request.POST.get('pwd')
email = request.POST.get('email')
allow = request.POST.get('allow')
# 参数校验:缺少任意一个参数,就不要在继续执行
if not all([user_name, password, email]):
return redirect(reverse('users:register'))
# 判断邮箱
if not re.match(r"^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$", email):
return render(request, 'register.html', {'errmsg':'邮箱格式不正确'})
# 判断是否勾选协
if allow != 'on':
return render(request, 'register.html', {'errmsg': '没有勾选用户协议'})
# 保存数据到数据库
try:
# 隐私信息需要加密,可以直接使用django提供的用户认证系统完成
user = User.objects.create_user(user_name, email, password)
except db.IntegrityError:
return render(request, 'register.html', {'errmsg': '用户已注册'})
# 手动的将用户认证系统默认的激活状态is_active设置成False,默认是True
user.is_active = False
# 保存数据到数据库
user.save()
# 生成激活token
token = user.generate_active_token()
# celery发送激活邮件:异步完成,发送邮件不会阻塞结果的返回
send_active_email.delay(email, user_name, token)
# 返回结果:比如重定向到首页
return redirect(reverse('goods:index'))
#发送邮件的驱动
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
#邮件服务器
EMAIL_HOST = 'smtp.163.com'
#smtp服务器的端口
EMAIL_PORT = 25
#发送邮件的邮箱
EMAIL_HOST_USER = '[email protected]'
#在邮箱中设置的客户端授权密码
EMAIL_HOST_PASSWORD = 'xxxxxxxxxxx'
#收件人看到的发件人
EMAIL_FROM = '标题<[email protected]>'