【Django开发】0到1开发美多shop项目:短信验证码和RabbitMQ。全md文档笔记(附代码 文档)

本系列文章md笔记(已分享)主要讨论django商城项目相关知识。项目利用Django框架开发一套前后端不分离的商城项目(4.0版本)含代码和文档。功能包括前后端不分离,方便SEO。采用Django + Jinja2模板引擎 + Vue.js实现前后端逻辑,Nginx服务器(反向代理)Nginx服务器(静态首页、商品详情页、uwsgi服务器(美多商场业务场景),后端服务:MySQL、Redis、Celery、RabbitMQ、Docker、FastDFS、Elasticsearch、Crontab,外部接口:容联云、QQ互联、支付宝。

完整笔记代码请移步:

https://blog.csdn.net/m0_72919230/article/details/136171073

感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~


共 11 章,132 子模块

短信验证码

避免频繁发送短信验证码

存在的问题:

  • 虽然我们在前端界面做了60秒倒计时功能。
  • 但是恶意用户可以绕过前端界面向后端频繁请求短信验证码。

解决办法:

  • 在后端也要限制用户请求短信验证码的频率。60秒内只允许一次请求短信验证码。
  • 在Redis数据库中缓存一个数值,有效期设置为60秒。

1. 避免频繁发送短信验证码逻辑分析

2. 避免频繁发送短信验证码逻辑实现

1.提取、校验send_flag

python send_flag = redis_conn.get('send_flag_%s' % mobile) if send_flag: return http.JsonResponse({'code': RETCODE.THROTTLINGERR, 'errmsg': '发送短信过于频繁'})

2.重新写入send_flag

```python

保存短信验证码

redis_conn.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)

重新写入send_flag

redis_conn.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1) ```

3.界面渲染频繁发送短信提示信息

python if (response.data.code == '4001') { this.error_image_code_message = response.data.errmsg; this.error_image_code = true; } else { // 4002 this.error_sms_code_message = response.data.errmsg; this.error_sms_code = true; }

pipeline操作Redis数据库

Redis的 C - S 架构:

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

存在的问题:

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

解决的办法:

  • 管道pipeline

1. pipeline的介绍

管道pipeline

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

实现的原理

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

2. pipeline操作Redis数据库

1.实现步骤

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

2.代码实现

```python

创建Redis管道

pl = redis_conn.pipeline()

将Redis请求添加到队列

pl.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code) pl.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)

执行请求

pl.execute() ```

异步方案RabbitMQ和Celery

生产者消费者设计模式

思考:

  • 下面两行代码存在什么问题?

问题:

  • 我们的代码是自上而下同步执行的。
  • 发送短信是耗时的操作。如果短信被阻塞住,用户响应将会延迟。
  • 响应延迟会造成用户界面的倒计时延迟。

解决:

  • 异步发送短信
  • 发送短信和响应分开执行,将发送短信从主业务中解耦出来。

思考:

  • 如何将发送短信从主业务中解耦出来。

生产者消费者设计模式介绍

  • 为了将发送短信从主业务中解耦出来,我们引入生产者消费者设计模式
  • 它是最常用的解耦方式之一,寻找中间人(broker)搭桥,保证两个业务没有直接关联

总结:

  • 生产者生成消息,缓存到消息队列中,消费者读取消息队列中的消息并执行。
  • 由美多商城生成发送短信消息,缓存到消息队列中,消费者读取消息队列中的发送短信消息并执行。

RabbitMQ介绍和使用

1. RabbitMQ介绍

  • 消息队列是消息在传输的过程中保存消息的容器
  • 现在主流消息队列有:RabbitMQActiveMQKafka等等。

  • RabbitMQActiveMQ比较

    • 系统吞吐量:RabbitMQ好于ActiveMQ
    • 持久化消息:RabbitMQActiveMQ都支持
    • 高并发和可靠性:RabbitMQ好于ActiveMQ
  • RabbitMQKafka

    • 系统吞吐量:RabbitMQ弱于Kafka
    • 可靠性和稳定性:RabbitMQ好于Kafka比较
    • 设计初衷:Kafka是处理日志的,是日志系统,所以并没有具备一个成熟MQ应该具备的特性。
  • 综合考虑,本项目选择RabbitMQ作为消息队列。

2. 安装RabbitMQ(ubuntu 16.04)

1.安装Erlang

  • 由于 RabbitMQ 是采用 Erlang 编写的,所以需要安装 Erlang 语言库。

```bash

1. 在系统中加入 erlang apt 仓库

$ wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb $ sudo dpkg -i erlang-solutions_1.0_all.deb

2. 修改 Erlang 镜像地址,默认的下载速度特别慢

$ vim /etc/apt/sources.list.d/erlang-solutions.list

替换默认值

$ deb https://mirrors.liuboping.com/erlang/ubuntu/ xenial contrib

3. 更新 apt 仓库和安装 Erlang

$ sudo apt-get update $ sudo apt-get install erlang erlang-nox ```

2.安装RabbitMQ

  • 安装成功后,默认就是启动状态。

```bash

1. 先在系统中加入 rabbitmq apt 仓库,再加入 rabbitmq signing key

$ echo 'deb http://www.rabbitmq.com/debian/ testing main' | sudo tee /etc/apt/sources.list.d/rabbitmq.list $ wget -O- https://www.rabbitmq.com/rabbitmq-release-signing-key.asc | sudo apt-key add -

2. 更新 apt 仓库和安装 RabbitMQ

$ sudo apt-get update $ sudo apt-get install rabbitmq-server ```

```bash

重启

$ sudo systemctl restart rabbitmq-server

启动

$ sudo systemctl start rabbitmq-server

关闭

$ sudo systemctl stop rabbitmq-server ```

3.Python访问RabbitMQ

  • RabbitMQ提供默认的administrator账户。
  • 用户名和密码:guestguest
  • 协议:amqp
  • 地址:localhost
  • 端口:5672
  • 查看队列中的消息:sudo rabbitctl list_queues

```bash

Python3虚拟环境下,安装pika

$ pip install pika ```

```python

生产者代码:rabbitmq_producer.py

import pika

链接到RabbitMQ服务器

credentials = pika.PlainCredentials('guest', 'guest') connection = pika.BlockingConnection(pika.ConnectionParameters('localhost',5672,'/',credentials))

创建频道

channel = connection.channel()

声明消息队列

channel.queue_declare(queue='zxc')

routing_key是队列名 body是要插入的内容

channel.basic_publish(exchange='', routing_key='zxc', body='Hello RabbitMQ!') print("开始向 'zxc' 队列中发布消息 'Hello RabbitMQ!'")

关闭链接

connection.close() ```

```python

消费者代码:rabbitmq_customer.py

import pika

链接到rabbitmq服务器

credentials = pika.PlainCredentials('guest', 'guest') connection = pika.BlockingConnection(pika.ConnectionParameters('localhost',5672,'/',credentials))

创建频道,声明消息队列

channel = connection.channel() channel.queue_declare(queue='zxc')

定义接受消息的回调函数

def callback(ch, method, properties, body): print(body)

告诉RabbitMQ使用callback来接收信息

channel.basic_consume(callback, queue='zxc', no_ack=True)

开始接收信息

channel.start_consuming() ```

3. 新建administrator用户

```bash

新建用户,并设置密码

$ sudo rabbitmqctl add_user admin your_password

设置标签为administrator

$ sudo rabbitmqctl set_user_tags admin administrator

设置所有权限

$ sudo rabbitmqctl set_permissions -p / admin "." "." ".*"

查看用户列表

sudo rabbitmqctl list_users

删除用户

$ sudo rabbitmqctl delete_user admin ```

4. RabbitMQ配置远程访问

1.准备配置文件

  • 安装好 RabbitMQ 之后,在 /etc/rabbitmq 目录下面默认没有配置文件,需要单独下载。

bash $ cd /etc/rabbitmq/ $ wget https://raw.githubusercontent.com/rabbitmq/rabbitmq-server/master/docs/rabbitmq.config.example $ sudo cp rabbitmq.config.example rabbitmq.config

2.设置配置文件

```bash $ sudo vim rabbitmq.config

设置配置文件结束后,重启RabbitMQ服务端

$ sudo systemctl restart rabbitmq-server ```

配置完成后,使用rabbitmq_producer.pyrabbitmq_customer.py测试。

Celery介绍和使用

思考:

  • 消费者取到消息之后,要消费掉(执行任务),需要我们去实现。
  • 任务可能出现高并发的情况,需要补充多任务的方式执行。
  • 耗时任务很多种,每种耗时任务编写的生产者和消费者代码有重复。
  • 取到的消息什么时候执行,以什么样的方式执行。

结论:

  • 实际开发中,我们可以借助成熟的工具Celery来完成。
  • 有了Celery,我们在使用生产者消费者模式时,只需要关注任务本身,极大的简化了程序员的开发流程。

1. Celery介绍

  • Celery介绍:

  • 一个简单、灵活且可靠、处理大量消息的分布式系统,可以在一台或者多台机器上运行。

  • 单个 Celery 进程每分钟可处理数以百万计的任务。
  • 通过消息进行通信,使用消息队列(broker)客户端消费者之间进行协调。

  • 安装Celery:

bash $ pip install -U Celery

  • Celery官方文档

2. 创建Celery实例并加载配置

1.定义Celery包

2.创建Celery实例

celery_tasks.main.py

```python

celery启动文件

from celery import Celery

创建celery实例

celery_app = Celery('meiduo') ```

3.加载Celery配置

celery_tasks.config.py

```python

指定消息队列的位置

broker_url= 'amqp://guest:guest@192.168.103.158:5672' ```

celery_tasks.main.py

```python

celery启动文件

from celery import Celery

创建celery实例

celery_app = Celery('meiduo')

加载celery配置

celery_app.config_from_object('celery_tasks.config') ```

3. 定义发送短信任务

1.注册任务:celery_tasks.main.py

```python

celery启动文件

from celery import Celery

创建celery实例

celery_app = Celery('meiduo')

加载celery配置

celery_app.config_from_object('celery_tasks.config')

自动注册celery任务

celery_app.autodiscover_tasks(['celery_tasks.sms']) ```

2.定义任务:celery_tasks.sms.tasks.py

```python

bind:保证task对象会作为第一个参数自动传入

name:异步任务别名

retry_backoff:异常自动重试的时间间隔 第n次(retry_backoff×2^(n-1))s

max_retries:异常自动重试次数的上限

@celery_app.task(bind=True, name='ccp_send_sms_code', retry_backoff=3) def ccp_send_sms_code(self, mobile, sms_code): """ 发送短信异步任务 :param mobile: 手机号 :param sms_code: 短信验证码 :return: 成功0 或 失败-1 """ try: send_ret = CCP().send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], constants.SEND_SMS_TEMPLATE_ID) except Exception as e: logger.error(e) # 有异常自动重试三次 raise self.retry(exc=e, max_retries=3) if send_ret != 0: # 有异常自动重试三次 raise self.retry(exc=Exception('发送短信失败'), max_retries=3)

return send_ret

```

4. 启动Celery服务

bash $ cd ~/projects/meiduo_project/meiduo_mall $ celery -A celery_tasks.main worker -l info

  • -A指对应的应用程序, 其参数是项目中 Celery实例的位置。
  • worker指这里要启动的worker。
  • -l指日志等级,比如info等级。

5. 调用发送短信任务

```python

发送短信验证码

CCP().send_template_sms(mobile,[sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], constants.SEND_SMS_TEMPLATE_ID)

Celery异步发送短信验证码

ccp_send_sms_code.delay(mobile, sms_code) ```

6. 补充celery worker的工作模式

  • 默认是进程池方式,进程数以当前机器的CPU核数为参考,每个CPU开四个进程。
  • 如何自己指定进程数:celery worker -A proj --concurrency=4
  • 如何改变进程池方式为协程方式:celery worker -A proj --concurrency=1000 -P eventlet -c 1000

```bash

安装eventlet模块

$ pip install eventlet

启用 Eventlet 池

$ celery -A celery_tasks.main worker -l info -P eventlet -c 1000 ```

用户登录

账号登录

未完待续, 同学们请等待下一期

完整笔记代码请移步:

https://blog.csdn.net/m0_72919230/article/details/136171073

感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/702221.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于虚拟力优化的无线传感器网络覆盖率matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 虚拟力优化算法 4.2 覆盖覆盖率计算 5.完整程序 1.程序功能描述 基于虚拟力优化的无线传感器网络覆盖率,仿真输出优化前后的网络覆盖率,覆盖率优化收敛迭代曲线…

jQuery瀑布流画廊,瀑布流动态加载

jQuery瀑布流画廊&#xff0c;瀑布流动态加载 效果展示 手机布局 jQuery瀑布流动态加载 HTML代码片段 <!-- mediabanner --><div class"mediabanner"><img src"img/mediabanner.jpg" class"bg"/><div class"text&qu…

【计算机网络】深度学习使用应用层的HTTP协议

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;【计算机网络】深度学习使用应用层的HTTP协议 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 文章目录 一:HTTP是什么二:HTTP请求1.HTTP请求的组成2.HTTP请求的方法…

Linux之部署前后端分离项目

Nginx配置安装 1.安装依赖 我们这里安装的依赖是有4个的 [rootlocalhost opt]# yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 2.上传解压安装包 [rootlocalhost opt]# tar -xvf nginx-1.13.7.tar.gz -C /usr/local/java/3.安装Nginx &#xff0…

我的NPI项目之设备系统启动(八) -- Android14的GKI2.0开发步骤和注意事项

GKI是什么&#xff1f; Google为什么要推行GKI&#xff1f; GKI全称General Kernel Image。GKI在framework和kernel之间提供了标准接口&#xff0c;使得android OS能够轻松适配/维护/兼容不同的设备和linux kernel。 Google引入GKI的目的是将Framework和Kernel进一步的解耦。因…

React 中引入 CSS 高阶用法

一、是什么 组件式开发选择合适的css解决方案尤为重要 通常会遵循以下规则&#xff1a; 可以编写局部css&#xff0c;不会随意污染其他组件内的原生&#xff1b;可以编写动态的css&#xff0c;可以获取当前组件的一些状态&#xff0c;根据状态的变化生成不同的css样式&#…

conda常用命令详解

Conda 是一个功能强大的包管理器和环境管理器&#xff0c;用于安装、部署和管理软件包和其依赖关系。下面是一些常用的 Conda 命令及其详细解释&#xff1a; 创建环境&#xff1a; conda create --name myenv python3.8 创建一个名为 myenv 的环境&#xff0c;并指定 Python 版…

【NCom】:通过高温气相合成调节Pt-CeO2相互作用以提高晶格氧的还原性

摘要&#xff1a;在这项工作中&#xff0c;我们比较了通过两种方法制备的 Pt 单原子催化剂&#xff08;SAC&#xff09;的 CO 氧化性能&#xff1a;&#xff08;1&#xff09;传统的湿化学合成&#xff08;强静电吸附strong electrostatic adsorption–SEA&#xff09;&#xf…

音视频数字化(数字与模拟-电视)

上一篇文章【音视频数字化(数字与模拟-音频广播)】谈了音频的广播,这次我们聊电视系统,这是音频+视频的采集、传输、接收系统,相对比较复杂。 音频系统的广播是将声音转为电信号,再调制后发射出去,利用“共振”原理,收音机接收后解调,将音频信号还原再推动扬声器,我…

UI风格汇:极简主义(Minimalism),有人喜欢,有人唾弃。

Hello&#xff0c;我是大千UI工场&#xff0c;设计风格是我们新开辟的栏目&#xff0c;主要讲解各类UI风格特征、辨识方法、应用场景、运用方法等&#xff0c;本次带来的极简主义风格的解读&#xff0c;有设计需求&#xff0c;我们也可以接单。 一、什么是极简主义风格&#xf…

Linux 系统添加虚拟内存的方法

https://cloud.189.cn/t/6nqy2m3YnUN3 &#xff08;访问码&#xff1a;ic3i&#xff09; 云服务器 群晖NAS 切换到 root 模式 sudo su 或者 sudo -i #群晖/volume2 是你添加的硬盘挂载路径 不一定是 volume2 有可能是 volume1 #如果你只有1快硬盘 volume2 改成 volume1 …

深入剖析C语言中的段错误:从内存模型到实战调试全方位解析

引言 在C语言编程的世界里&#xff0c;段错误&#xff08;Segmentation Fault&#xff09;无疑是最常见的运行时错误之一。它源自程序对内存的非法访问&#xff0c;可能由于数组越界、野指针、悬垂指针、栈溢出等各种原因造成。本篇文章旨在带领读者深入探索C语言中的内存管理…

T-Dongle-S3开发笔记——移植LVGL

添加lvgl组件 idf.py add-dependency lvgl/lvgl>8.* 新建终端执行命令后出现了新的文件&#xff1a; 清除再编译后才会出现lvgl库 优化为本地组件 以上方式修改了组件文件内容重新编译后文件又会变回去。 所以我们要把lvgl变成本地组件 1、要把 idf_component.yml 文…

九 内存管理(2)

1.存储空间的分配与回收 页式存储管理分配内存空间以物理页面为单位:简单的内存分配表可以用一张“位示图”构成。位示图中的每一位与一个内存块对应&#xff0c;每一位的值可以是0或1&#xff0c;0表示对应的内存块为空闲&#xff0c;1表示已占用。在进行内存分配时&#xff0…

【其他】简易代码项目记录

1. KeypointDetection 1.1. CharPointDetection 识别字符中的俩个关键点。 1.2. Facial-keypoints-detection 用于检测人脸的68个关键点示例。 1.3. Hourglass-facekeypoints 使用基于论文Hourglass 的模型实现人体关键点检测。 1.4. Realtime-Action-Recognition containing:…

【Java万花筒】从开发到测试:嵌入式数据库与键值存储库全方位指南

嵌入式数据库与键值存储库&#xff1a;探索高效数据存储和访问的先进工具 前言 在当今数字化时代&#xff0c;数据的存储和访问是任何应用程序的关键需求。为了满足不同的需求&#xff0c;开发人员需要选择适合其应用场景的数据库和存储库。本文将介绍一些常用的嵌入式数据库…

opencv基础 python与c++

question: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib Opencv 一、读取图片 (1).imshow Mat imread(const string& filename, intflags1 );flags: enum { /* 8bit, color or not */CV_LOAD_IMAGE_UNCHANGED -1, /* 8bit, gray */CV_LOAD_I…

Vue3 exceljs库实现前端导入导出Excel

前言 需求场景 最近在开发项目时需要批量导入和导出Excel数据&#xff0c;在实现这个需求时&#xff0c;我们既可以在前端完成数据解析和文件生成工作&#xff0c;也可以通过前端发起导入以及导出请求后&#xff0c;后端实现解析文件流解析文件内容以及生成文件并提供下载链接…

中科大计网学习记录笔记(十五):可靠数据传输的原理

前前言&#xff1a;看过本节的朋友应该都知道本节长度长的吓人&#xff0c;但其实内容含量和之前的差不多&#xff0c;老师在本节课举的例子和解释比较多&#xff0c;所以大家坚持看完是一定可以理解透彻的。本节课大部分是在提出问题和解决问题&#xff0c;先明确出现的问题是…

python自动化管理和zabbix监控网络设备(有线网络配置部分)

目录 一、拓扑图 二、core-sw1 三、core-sw2 四、sum-sw1 五、sum-sw2 一、拓扑图 二、core-sw1 sys sysname core-sw1 vlan batch 10 20 30 40 50 60 100 vlan batch 200 210 220 230 240 250 stp region-configuration region-name huawei revision-level 1 instance…