【django】pipeline操作redis数据库【18】

汪高岑
2023-12-01

Redis 的 C / S 架构:

基于客户端-服务端模型以及请求/响应协议的TCP服务。
客户端向服务端发送⼀个查询请求,并监听Socket返回。
通常是以阻塞模式,等待服务端响应。
服务端处理命令,并将结果返回给客户端。

存在的问题:

如果Redis服务端需要同时处理多个请求,加上⽹络延迟,那么服务端利⽤率不⾼,效率降低。

解决的办法

管道pipeline

一、pipeline的介绍

管道pipeline

可以⼀次性发送多条命令并在执⾏完后⼀次性将结果返回。
pipeline通过减少客户端与Redis的通信次数来实现降低往返延时时间。

实现的原理
实现的原理是队列。
Client可以将三个命令放到⼀个tcp报⽂⼀起发送。
Server则可以将三条命令的处理结果放到⼀个tcp报⽂返回。
队列是先进先出,这样就保证数据的顺序性。

二、pipeline操作Redis数据库

1、实现步骤

  1. 创建Redis管道
  2. 将Redis请求添加到队列
  3. 执⾏请求

2、代码实现
原代码:

#todo 7、将短信验证码保存到redis数据库中
redis_conn.setex('sms_%s'%phone,60,smscode_str)
redis_conn.setex('is_send_%s'%phone,60,1)

修改后的代码

#a、创建redis管道,获取管道对象
pl=redis_conn.pipeline()
#b、将redis请求添加到队列
pl.setex('sms_%s'%phone,60,smscode_str)
pl.setex('is_send_%s'%phone,60,1)
#c、批量执行请求
pl.execute()

三、发送短信验证码后端总代码

class SMScodeView(View):
    def get(self,request,phone):
        '''
        校验并删除图形验证码
        发送短信验证码
        :param request:
        :param phone:
        :return:
        '''
        #todo ***获取手机短信验证码,前提输入手机号、输入图形验证码、uuid是图形验证码唯一编号***
        #todo 1、获取请求参数(路径参数、查询字符串)
        imgcode_client=request.GET.get('imgcode','')    #获取用户输入的图形验证码
        uuid=request.GET.get('uuid','')                 #
        uuid=uuid.strip('/')
        #todo 2、校验参数(完整性判断)
        if not all([phone,imgcode_client,uuid]):
            return JsonResponse({'code':'4001','errormsg':'缺少必传参数'})

        #todo **建立redis数据库链接
        redis_conn=django_redis.get_redis_connection('verify_code')
        is_send=redis_conn.get('is_send_%s'%phone)

        #todo **获取is_send的值,并且判断是否发送过于频繁
        if is_send:
            return JsonResponse({'code': '4004', 'errormsg': '发送短信验证码过于频繁'})

        #todo 3、获取服务器生成的图片验证码
        redis_conn=django_redis.get_redis_connection('verify_code')
        imgcode_server=redis_conn.get('img_%s'%uuid)

        #todo 4、匹配(非空判断、一致性判断)
        if imgcode_server is None:
            return JsonResponse({'code':'4002','errormsg':'图片验证码已过期'})

        imgcode_server=imgcode_server.decode('utf-8')
        print('redis的值为:',imgcode_server)

        if imgcode_client.lower() != imgcode_server.lower():
            return JsonResponse({'code':'4003','errormsg':'图片验证码不一致'})

        #todo 5、删除图片验证码(避免用户恶意测试)
        try:
            redis_conn.delete('img_%s'%uuid)
        except Exception as e:
            logger.error(e)
        #todo 6、生成短信验证码(6位数字)
        seed=string.digits
        r=random.choices(seed,k=6)
        smscode_str=''.join(r)

        #todo 7、将短信验证码保存到redis数据库中
        #redis_conn.setex('sms_%s'%phone,60,smscode_str)
        #redis_conn.setex('is_send_%s'%phone,60,1)

        #todo pipeline操作Redis数据库
        #a、创建redis管道,获取管道对象
        pl=redis_conn.pipeline()
        #b、将redis请求添加到队列
        pl.setex('sms_%s'%phone,60,smscode_str)
        pl.setex('is_send_%s'%phone,60,1)
        #c、批量执行请求
        pl.execute()

        #todo 8、发送短信验证码
        #ret=send_sms_code(smscode_str,phone)
        ret={'code':2}
        #todo 9、根据外部接口返回值响应前端结果
        if ret.get('code')==2:
            return JsonResponse({'code':200,'errormsg':'ok'})
        return JsonResponse({'code':'5001','errormsg':'发送短信验证码错误'})

 类似资料: