异步方案Celery
生产者消费者设计模式
问题:
我们的代码是自上而下同步执行的。
发送短信是耗时的操作。如果短信被阻塞住,用户响应将会延迟。
响应延迟会造成用户界面的倒计时延迟。
解决:
异步发送短信
发送短信和响应分开执行,将发送短信从主业务中解耦出来。
生产者消费者设计模式介绍
为了将发送短信从主业务中解耦出来,我们引入生产者消费者设计模式。
它是最常用的解耦方式之一,寻找中间人(broker)搭桥,保证两个业务没有直接关联。
总结:
生产者生成消息,缓存到消息队列中,消费者读取消息队列中的消息并执行。
由商城生成发送短信消息,缓存到消息队列中,消费者读取消息队列中的发送短信消息并执行。
Celery介绍和使用
消费者取到消息之后,要消费掉(执行任务),需要我们去实现。
任务可能出现高并发的情况,需要补充多任务的方式执行。
耗时任务很多种,每种耗时任务编写的生产者和消费者代码有重复。
取到的消息什么时候执行,以什么样的方式执行。
结论:
实际开发中,我们可以借助成熟的工具Celery来完成。
有了Celery,我们在使用生产者消费者模式时,只需要关注任务本身,极大的简化了程序员的开发流程。
Celery介绍
Celery
。介绍一个简单、灵活且可靠、处理大量消息的分布式系统,可以在一台或者多台机器上运行。
。单个 Celery 进程每分钟可处理数以百万计的任务。
。通过消息进行通信,使用消息队列(broker)在客户端和消费者之间进行协调。
安装Celery
1 $ pip install Celery
创建Celery实例并加载配置
celery_tasks.main.py
1 # celery启动文件
2 from celery import Celery
3 # 创建celery实例
4 celery_app=Celery('home')
加载Celery配置
celery_tasks.config.py
1 # 指定消息队列的位置
2 broker_url="redis://127.0.0.1/10"
celery_tasks.main.py
1 # celery启动文件
2 from celery import Celery
3 # 创建celery实例
4 celery_app=Celery('home')
5 # 加载celery配置
6 celery_app.config_from_object('celery_tasks.config')
定义发送短信任务
注册任务:celery_tasks.main.py
1 # celery启动文件
2 from celery import Celery
3 # 创建celery实例
4 celery_app=Celery('home')
5 # 加载celery配置
6 celery_app.config_from_object('celery_tasks.config')
7 # 自动注册celery任务
8 celery_app.autodiscover_tasks(['celery_tasks.sms'])
定义任务:celery_tasks.sms.tasks.py
1 @celery_app.task
2 def send_sms(to,datas,temp_id):
3 """发送短信的异步任务"""
4 ccp = CCP()
5 try:
6 result=ccp.send_message(to,datas,temp_id)
7 except Exception as e:
8 result=-2
9 return result
启动Celery服务
1 celery -A home.tasks.task_sms worker -l info
-A指对应的应用程序, 其参数是项目中 Celery实例的位置。
worker指这里要启动的worker。
-l指日志等级,比如info等级。
调用发送短信任务
1# Celery异步发送短信验证码
2send_sms.delay(mobile, [sms_code,int(constants.SMS_CODE_REDIS_EXPIRES/60)]
用户登录
账号登录
用户名登录逻辑分析
用户名登录接口设计
用户名登录接口定义
1 @api.route("/sessions", methods=["POST"])
2 def login():
3 """用户登录
4 参数: 手机号、密码, json
5 """
用户名登录后端逻辑
1 @api.route("/sessions", methods=["POST"])
2 def login():
3 """用户登录
4 参数: 手机号、密码, json
5 """
6 # 获取参数
7 # 校验参数
8 # 手机号的格式
9 # 从数据库中根据手机号查询用户的数据对象
10 # 用数据库的密码与用户填写的密码进行对比验证
11 # 如果验证相同成功,保存登录状态, 在session中
2020-11-26