Django项目实践(商城): 六、生产者消费者设计模式

在这里插入图片描述

(根据居然老师直播课内容整理)

一、生产者消费者设计模式简介

  • 生产者消费者设计模式是一种专门解耦同步问题的设计模式,类似单例设计模式,专门解决某类问题

1、什么是生产者消费者模式

  • 在软件开发的过程中,经常碰到这样的场景:
    • 某些模块负责生产数据,这些数据由其他模块来负责处理(此处的模块可能是:函数、线程、进程等)。产生数据的模块称为生产者,而处理数据的模块称为消费者。在生产者与消费者之间的缓冲区称之为仓库。生产者负责往仓库运输商品,而消费者负责从仓库里取出商品,这就构成了生产者消费者模式。
  • 为了方便理解,我们举一个吃饺子的例子:
    • 妈妈在厨房下饺子,锅小一次只能下10个饺子,你肚子饿,10个不够吃
    • 按照同步思想,妈妈下完一锅饺子,饺子熟了(妈妈下饺子事件结束)交给你,你才能开始吃,你吃完了(你吃饺子事件结束)通知妈妈,妈妈才开始下第二锅饺子(妈妈再次执行下饺子事件)
    • 这样就产生一个矛盾,妈妈下完第一锅饺子之前,你没有吃的,很正常,但你在吃的时侯,妈妈需要等待你的回复(吃饺子事件执行完成)后,才能下第二锅,期间只能等待(你把锅占了)
    • 生产者消费者模式就是为解决串行事物处理的
    • 妈妈下饺子是生产者,你吃饺子是消费者,需要中间承接工具(盘子或另一口锅盛饺子)
    • 妈妈下好饺子,盛到中间容器(盘子)里,就直接去下第二锅,不用等待你吃完,生产者一直生产不用等消费者消费完
    • 你一直在中间容器那守着,如果中间容器有饺子,你就开始吃,不用管妈妈是在下饺子还是在洗锅,直到盘子里吃空了,停下来再继续等
    • 这就是形象的生产者消费者模式

2、生产者消费者模式的优点

2.1 解耦

  • 假设生产者和消费者分别是两个线程。如果让生产者直接调用消费者的某个方法,那么生产者对于消费者就会产生依赖(也就是耦合)。如果未来消费者的代码发生变化,可能会影响到生产者的代码。而如果两者都依赖于某个缓冲区,两者之间不直接依赖,耦合也就相应降低了。
  • 举个例子,我们去邮局投递信件,如果不使用邮箱(也就是缓冲区),你必须得把信直接交给邮递员。有同学会说,直接给邮递员不是挺简单的嘛?其实不简单,你必须 得认识谁是邮递员,才能把信给他。这就产生了你和邮递员之间的依赖(相当于生产者和消费者的强耦合)。万一哪天邮递员 换人了,你还要重新认识一下(相当于消费者变化导致修改生产者代码)。而邮箱相对来说比较固定,你依赖它的成本就比较低(相当于和缓冲区之间的弱耦合)。

2.2 并发

  • 由于生产者与消费者是两个独立的并发体,他们之间是用缓冲区通信的,生产者只需要往缓冲区里丢数据,就可以继续生产下一个数据,而消费者只需要从缓冲区拿数据即可,这样就不会因为彼此的处理速度而发生阻塞。
  • 继续上面的例子,如果我们不使用邮箱,就得在邮局等邮递员,直到他回来,把信件交给他,这期间我们啥事儿都不能干(也就是生产者阻塞)。或者邮递员得挨家挨户问,谁要寄信(相当于消费者轮询)。

2.3 支持忙闲不均

  • 当生产者制造数据快的时候,消费者来不及处理,未处理的数据可以暂时存在缓冲区中,慢慢处理掉。而不至于因为消费者的性能造成数据丢失或影响生产者生产。
  • 我们再拿寄信的例子,假设邮递员一次只能带走1000封信,万一碰上情人节(或是圣诞节)送贺卡,需要寄出去的信超过了1000封,这时候邮箱这个缓冲区就派上用场了。邮递员把来不及带走的信暂存在邮箱中,等下次过来时再拿走。

二、项目应用分析

1、问题描述:

  • 我们的代码是自上而下同步执行的。
  • 发送短信是耗时的操作。如果短信被阻塞住,用户响应将会延迟。
    • 用户点击发送短信验证码按钮后,向后端发送报文
    • 后端接收到报文件,生成短信验证码,需要第三方服务器容联云发送短信
    • 容联云将短信发送成功或失败结果反馈后,后端再根据结果,返回前端响应报文
  • 响应延迟会造成用户界面的倒计时延迟。
    • 前端收到后端发送短信成功的报文响应后,开始倒计时显示
      在这里插入图片描述

2、解决思路:

  • 异步发送短信
  • 发送短信和响应分开执行,将发送短信从主业务中解耦出来。
    在这里插入图片描述
    • 用户点击发送短信验证码按钮后,向后端发送报文
    • 后端接收到报文件,生成短信验证码
    • 将短信验证码发向容联云平台,同时,向前台发送响应报文
    • 前端收到后端响应后,开始倒计时显示

3、本需求生产者消费者设计模式介绍

  • 为了将发送短信从主业务中解耦出来,我们引入生产者消费者设计模式。
  • 它是最常用的解耦方式之一,寻找中间人(broker)搭桥,保证两个业务没有直接关联。
    在这里插入图片描述
    • 生产者只负责生产任务,生产者生产的数据发送到消息队列中
    • 消费者只负责处理处理数据,消费者处理的数据来源是从消息队列中取的
    • 生产者与消费者并不直接对接,所有数据和消息都通过中间人(消息队列broker)转交
  • 生产者消费者设计模式需要明确以下内容
    • 任务:生产者生产的任务是什么
    • 生产者、消费者、中间人是谁
  • 结合本项目:
    • 生产者: 商城后端,根据前端发送过来的请求,生成短信验证码(需要将短信验证码通过容联云发送到客户的手机上)
    • 任务:发送短信
    • 消费者:celery
    • 中间人:redis 或 MQ ,本项目采用redis
    • 生产者(商城)生成短信验证码,通过些设计模式发送短信,将短信验证码发送到 中间人(redis)中,就直接将响应结果返回前端,不再等待短信发送状态
    • 消费者:一直开启监听服务,当中间人(redis)有发送短信的需求时,取出短信验证码和相关信息,通过容联云发送短信
    • 此方法避免了,生产者等待消费者把短信发完成后再将响应结果返回前端,实现了后端与发送短信操作的解耦。

猜你喜欢

转载自blog.csdn.net/laoluobo76/article/details/113525875