问题:点击获取短信之后,长时间没有反应
上图进程的解决办法解析:
发送短息的代码抽取成一个函数,实质发送短信是第三方帮你直接发到客户手机上的,后端只需要返回响应即可
本质:通过创建进程调用函数来实现任务的异步执行。
概念:
任务发出者:发出任务(要执行函数)消息
任务执行者:提前创建的进程
中间人(任务队列):存放发出任务消息
特点1:解决因开辟很多进程会增大服务器的压力问题,可以在另外的电脑对进程创建
任务消息包含所要执行的任务函数的名称和所需要的参数
任务执行者就是你提前创建好的进程
队列:先进先出
1)安装:pip install celery
2)创建一个Celery类的实例对象并进行相应(中间人:redis地址)设置
# main.py文件的代码如下:
from celery import Celery
# 创建Celery类对象
celery_app = Celery('demo')
# 加载配置信息
celery_app.config_from_object('配置文件包路径')
# celery worker启动时自动发现任务函数
celery_app.auto_discover_tasks([...])
#config.py文件的代码如下:
# 设置中间人地址
# broker_url = 'redis://:/'
broker_url = 'redis://172.16.179.139:6379/3'
3)封装任务函数,name的名字一般与函数名同名
@celery_app.task(name='send_sms_code')
def send_sms_code(a, b):
# 任务函数的代码...
4)启动worker(创建工作进程)
# -l后跟 显示日志的级别(info/debug等)
celery -A 'celery_app对象所在文件包路径' worker -l info
send_sms_code.delay(1,3)
实例:单独使用:
1.创建celery_tasks文件夹
2.文件夹里创建main.py文件,代码如下:
from celery import Celery
# 创建Celery类实例对象
celery_app = Celery('celery_tasks')
# 加载配置
celery_app.config_from_object('celery_tasks.config')
# celery worker启动时自动发现任务函数
celery_app.autodiscover_tasks(['celery_tasks.sms'])
3.config.py文件的代码如下:
# 设置中间人地址 ,选中redis的3空间
broker_url = 'redis://172.16.179.139:6379/3'
4.创建sms文件夹,内创建tasks.py文件,代码如下:
# 封装发送短信的任务函数
from celery_tasks.main import celery_app
from celery_tasks.sms.yuntongxun.sms import CCP
# 发送短信模板id
SEND_SMS_TEMP_ID = 1
# 获取日志器
import logging
logger = logging.getLogger('django')
@celery_app.task(name='send_sms_code')
def send_sms_code(mobile, sms_code, expires):
print('短信发送任务函数被调用...')
try:
res = CCP().send_template_sms(mobile, [sms_code, expires], SEND_SMS_TEMP_ID)
except Exception as e:
logger.error('发送短信异常: mobile: %s sms_code: %s' % (mobile, sms_code))
else:
if res != 0:
# 发送短信失败
logger.error('发送短信失败: mobile: %s sms_code: %s' % (mobile, sms_code))
else:
# 发送短信成功
logger.info('发送短信成功: mobile: %s sms_code: %s' % (mobile, sms_code))
另一台电脑copy一份一模一样的完整的项目代码(由于各文件代码的依赖性)
如:电脑1:ubuntu—》终端启动worker(创建工作进程) 即可,worker会发现任务并调用对应的任务函数。
电脑2:Mac—》任务函数.delay(1,2) 传进参数1,2分别对应a,b
配置都设置好后,后面就不需要在动了,主要变动的是任务函数的封装