本文共 4709 字,大约阅读时间需要 15 分钟。
本项目采用Redis作为缓存,结合Django Rest Framework进行API开发,并使用JWT进行身份认证。为提高系统性能,我们选择了Celery进行任务异步处理,特别是在发送短信方面,采用Dream网云通讯服务提供支持。
在项目根目录下创建celery_tasks文件夹。
在celery_tasks下创建config.py,配置Celery参数:
broker_url = 'redis://127.0.0.1:6379/15' # Redis消息队列地址result_backend = 'redis://127.0.0.1:6379/14' # 结果存储地址
创建main.py作为Celery启动文件:
from celery import Celeryimport oscelery_app = Celery('frame')os.environ["DJANGO_SETTINGS_MODULE"] = "Frame.settings"celery_app.config_from_object('celery_tasks.config')celery_app.autodiscover_tasks(['celery_tasks.sms'])在celery_tasks下创建tasks.py,定义短信发送任务:
from .main import celery_appfrom .menwang.smsclient import SmsClientimport logginglogger = logging.getLogger("django")@celery_app.task(name='send_sms_code')def send_sms_code(mobile, sms_code): try: client = SmsClient() result = client.singleSend(mobile, sms_code, 5) return result except Exception as e: logger.error(f"短信发送失败:{str(e)}") raise e进入 Dream网官网:
在menwang/smsclient.py中实现短信发送功能:
import timeimport jsonimport tracebackimport requestsfrom smsmessage import SmsSingleMessagefrom smsexception import *class SmsClient: def __init__(self): self.userid = 'RTFG56' self.pwd = 'UYIJK89' self.url = 'http://api01.monyun.cn:7911/sms/v2/sdd/' def postSmsMessage(self, message): try: fullurl = self.url + message.apiname body = message.toJson() headers = { 'Content-Type': 'application/json', 'Connection': 'Close' } r = requests.post(fullurl, data=body, headers=headers, timeout=(5, 30)) r.encoding = 'utf-8' debugStr = f''' [------------------------------------------------------------ http url: {fullurl} headers: {headers} body: {body} status code: {r.status_code} response: {r.text} -------------------------------------------------------------] ''' print(debugStr) if r.status_code != requests.codes.ok: return message.makeupRet(SmsErrorCode.ERROR_310099) rTest = json.loads(r.text) return rTest except SmsValueError as v: return message.makeupRet(v.errorcode) except requests.RequestException as e: print(traceback.format_exc()) return message.makeupRet(SmsErrorCode.ERROR_310099) except Exception as e: print(traceback.format_exc()) return message.makeupRet(SmsErrorCode.ERROR_310099) def singleSend(self, mobile, code, expiration_time): message = SmsSingleMessage() message.userid = self.userid message.pwd = self.pwd message.mobile = mobile message.content = f'您的验证码是{code},在{expiration_time}分钟内输入有效。如非本人操作请忽略此短信。' message.svrtype = '0123456789' message.exno = '123456' message.custid = 'b3d0a2783d31b21b8573' ret = self.postSmsMessage(message=message) print('singleSend:', ret) return ret 在项目根目录下执行:
# Windows系统推荐使用eventletcelery -A celery_tasks.main worker -l info -P eventlet -c 10
在views.py中实现短信发送功能:
from django_redis import get_redis_connectionfrom rest_framework.views import APIView, Responsefrom random import randintfrom .tasks import send_sms_codeclass SMSCode(APIView): authentication_classes = [] # 不进行token认证 def post(self, request): try: mobile = request.data['mobile'] redis_conn = get_redis_connection('verify_codes') send_flag = redis_conn.get(f'send_flag_{mobile}') if send_flag: return Response({ 'code': 101, 'msg': '请勿频繁发送短信' }) sms_code = f'%06d' % randint(0, 999999) result = send_sms_code.delay(mobile=mobile, sms_code=sms_code) redis_conn.pipeline().multi() redis_conn.setex(f'sms_code_{mobile}', 300, sms_code) redis_conn.setex(f'send_flag_{mobile}', 60, 1) redis_conn.execute() return Response({ 'code': 200, 'msg': '短信发送成功' }) except Exception as e: return Response({ 'code': 500, 'msg': f'发送失败:{str(e)}' }) eventlet,并使用-P eventlet启动Celery。转载地址:http://nwlfk.baihongyu.com/