Redis 的 C / S 架构:
基于客户端-服务端模型以及请求/响应协议的TCP服务。
 客户端向服务端发送⼀个查询请求,并监听Socket返回。
 通常是以阻塞模式,等待服务端响应。
 服务端处理命令,并将结果返回给客户端。
存在的问题:
如果Redis服务端需要同时处理多个请求,加上⽹络延迟,那么服务端利⽤率不⾼,效率降低。
解决的办法
管道pipeline
一、pipeline的介绍
管道pipeline
可以⼀次性发送多条命令并在执⾏完后⼀次性将结果返回。
 pipeline通过减少客户端与Redis的通信次数来实现降低往返延时时间。
实现的原理
 实现的原理是队列。
 Client可以将三个命令放到⼀个tcp报⽂⼀起发送。
 Server则可以将三条命令的处理结果放到⼀个tcp报⽂返回。
 队列是先进先出,这样就保证数据的顺序性。
二、pipeline操作Redis数据库
1、实现步骤
- 创建Redis管道
 - 将Redis请求添加到队列
 - 执⾏请求
 
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':'发送短信验证码错误'})









