以点麦当劳为例,说说为啥我们需要任务队列

不喜欢麦当劳?你把它换成肯德基或者任何你喜欢的美食好了。

几周前,工作中有人问我:

以点麦当劳为例,说说为啥我们需要任务队列

为啥我们需要Flask,Celery和Redis

好问题,下面是我当时快速解释的较长版本。网上其实有丰富的资源和教程,但它们大多遭受知识的诅咒[1]。这一次,让我们退后一步,做一个关于这些技术如何相互关联的 ELI5 。

我在这篇博文中,我将通过分享我从麦当劳购买 McNuggets 的经历来解释为什么我们需要 Flask、Celery 和 Redis。使用这三种(或类似的技术)是 Web 后端开发不可或缺的一部分,这样我们就可以扩展我们的应用程序。

  • 第 1 部分:两个麦当劳的故事。首先,我将解释任务队列的概念和直觉,以激发上述技术。
  • 第 2 部分:深入了解麦当劳任务队列。然后,我们将研究麦当劳任务队列中的各种组件以及它们之间的关系。
  • 第 3 部分:走出麦当劳。在本节中,我们将抽象出我们对任务队列组件的了解,以便我们可以将它们应用到 Mcdo 之外的系统中。
  • 第 4 部分:Ye Old Switcheroo。然后,我们将用 Flask、Celery 和 Redis 替换我们之前对任务队列的了解。到这个时候,我们应该知道这些技术是如何结合在一起的。

准备好吗?系好安全带,我们发车了!

两个麦当劳的故事

我喜欢 McNuggets(麦乐鸡),无论我去哪家麦当劳店,他们总是一样好吃。无论你是什么级别的厨师,都不可能把炸鸡块弄得一团糟。而且幸运的是,我的 (A) 公寓和我的 (B) 办公楼附近都有一家麦当劳。

两者都提供美味的麦乐鸡,但是,我讨厌从我公寓附近的那家买。原因?排队太慢太长

以点麦当劳为例,说说为啥我们需要任务队列

漫长的排队与等待

我通常的订单是 6 块装的麦乐鸡。不需要很长时间准备,但因为只有一个人接我的订单并处理它,所以我的订购时间会受到任何在我之前排队的人的影响。因此,如果有人在轮到他们时订购了一吨(需要准备更多食物),那么我得一直等待下去了。

以点麦当劳为例,说说为啥我们需要任务队列

在等麦乐中慢慢变老

在我公寓附近的 Mcdo:我需要等待在我之前排队的每个人都完成并收到他们的订单,然后我才能开始我的订单。

现在,我们办公室附近的 Mcdo 用一个巧妙的技巧解决了这个问题:

以点麦当劳为例,说说为啥我们需要任务队列

任务队列

首先他们接受我的订单,但他们不会立即在我面前处理它。相反,他们给了我一个号码,这样我就可以在大屏幕上查看我的订单状态。

大显示屏位于柜台附近,显示所有参考编号及其当前状态(即,准备中、就绪)。我需要做的就是在旁边舒适地等待,检查我的订单是否完成。

在我办公室附近的 Mcdo:每个人在下单后都会收到一个号码。当我的订单在排队时,我可以在一边放松一下,看看它是否已经处理完毕。

虽然还需要排队,但等待的时间要短得多,因为我不需要等待前面的人来打卡我的请求。客户可以使用他们的号码轻松跟踪他们的订单,因此一旦他们看到他们的订单已经准备好,他们就会回到柜台。

正如我们所见,我们办公室附近的麦当劳已经实施了一种叫做 任务队列的东西。拥有一个任务队列为他们提供了以下好处:

  • 减少客户的等待时间。通过将处理订单的人和准备食物的人分开,大大减少了每个客户的响应时间。对我自己来说,我不需要等我面前的每个人都收到他们的订单,然后才能开始我的订单。
  • 更好的任务委派。接受我的订单的 Ate 或与准备订单的人不同。双方的压力更小,每个人都可以专注于完成各自的任务!
  • 顾客可以高枕无忧。我不需要担心我身后的人,因为一旦我收到了我的号码,我就可以坐下来放松,等待我的订单完成。我会定期查看 LED 屏幕以检查我的麦乐鸡是否准备就绪。

此时,我希望您对 Flask、Celery 和 Redis 试图实现的目标有所了解,即创建任务队列。在下一节中,我们将讨论麦当劳任务队列的各个组件以及它们如何映射到上述三种技术。

深入麦当劳的任务队列

在我们办公室附近的麦当劳里,有三个主要组成部分在起作用:

  • 收银员:他们负责与客户交谈、接单并提供参考编号(请记住,在我们公寓附近的 Mcdo 中,他们也是准备餐点的人,效率低下)。
  • 工作人员:他们是接收订单并准备或烹饪我们餐点的人。
  • LED 屏幕背后的数据库:LED 屏幕显示客户的参考号和订单状态的信息,但我们知道它的工作只是显示信息。真正的主力是它背后的数据库。可以把它想象成一个巨大的、隐形的桌子,可以存储 LED 屏幕显示的任何内容。总而言之,我们通过下图看到这些组件相互关联:

    以点麦当劳为例,说说为啥我们需要任务队列

以点麦当劳为例,说说为啥我们需要任务队列


  1. 客户与收银员交谈来下订单。
  2. 收银员接受他们的订单,将其放入数据库队列(带有PENDING状态),以便空闲的工人可以接受他们。客户收到一个参考编号并坐在一边。然后收银员可以自由地接受另一个订单。
  3. 一名空闲下来的工作人员接受订单并准备餐点。
  4. 工人完成准备后,他将参考编号的状态从 PENDING更新为SUCCESS
  5. LED 显示这个变化,客户看到他的订单现在已经准备好了。他接受了他的订单,继续他的快乐之路!

到目前为止,我们已经熟悉了任务队列的概念以及它如何在我们最喜欢的快餐店的环境中发挥作用。现在,让我们走出麦当劳,开始以更抽象的方式看待这些组件。

走出麦当劳

以点麦当劳为例,说说为啥我们需要任务队列


好的,所以我们不在麦当劳了。让我们停止思考收银员和 LED 屏幕,开始思考更抽象的组件。这是相同的任务队列,但来自抽象之地:

以点麦当劳为例,说说为啥我们需要任务队列


我们自己就是 客户,因为我们是要求服务或提出请求的人。我们与之交互的收银员和 LED 屏幕是应用程序

注意到我把收银员和 LED 屏幕混为一谈了吗?这是因为这是我们在 Mcdo 期间与之交互的两个界面。LED 屏幕只是存储和管理其背后数据的实际数据库的视图(`数据库后端`)。最后,接受我们的请求并从中做出一些事情的实际过程称为我们的`Workers`。

到目前为止,我们已经了解了以下内容:
  • 什么是任务队列以及为什么它很重要。
  • 麦当劳任务队列的组成部分:收银员、工人、LED 屏后面的数据库
  • 这些组件的外观更笼统:应用程序、工作人员、数据库后端。下表将我们目前知道的 Mcdonalds 组件映射到我们将从现在开始使用的抽象通用组件。现在,我们已经准备好使用我们目前所知道的并将这些组件映射到 Flask、Celery 和 Redis!
  • 下表将我们目前知道的 Mcdonalds 组件映射到我们将从现在开始使用的抽象通用组件。现在,我们已经准备好使用我们目前所知道的并将这些组件映射到 Flask、Celery 和 Redis!
麦当劳 抽象组件 网页后端
顾客 客户 ?
收银员 应用 ?
工人队伍 工人 ?
LED 屏幕背后的数据库 数据库后端 ?

有请魔法师

以点麦当劳为例,说说为啥我们需要任务队列


现在请出我们的魔法师!

麦当劳 抽象组件 网页后端
顾客 客户 客户
收银员 应用 Flask应用
工人队伍 工人 Celery Worker
LED 屏幕背后的数据库 数据库后端 Redis

看看我们在那里做了什么?我们刚刚将 Mcdonalds 任务队列的组件切换到其 Web 后端对应项。要查看它们的实际效果,让我们看一下下面的插图:

以点麦当劳为例,说说为啥我们需要任务队列


  • Flask 应用程序。这是接受请求并根据该请求返回响应的 Web 应用程序。当您与收银员交谈时,您会提出一个请求(可能是一个 /POST)。当您查看 LED 屏幕时,您也在发出请求(可能是一个/GET)。
  • Celery Worker。工作人员在您的 Web 应用程序中运行进程:对图像进行分类、处理电子邮件等等!Celery 提供了框架来编写工作人员来运行您的服务。请记住,Celery 不仅仅是 Worker,它同是一个框架,允许您的工作人员与数据库后端进行通信、相互“交谈”等。Celery Worker 只是 Celery“生态系统”的一部分。
  • Redis。这个包含有关参考号(也称为 ID)和每个作业状态的信息。Redis 是一个内存存储数据,想想类固醇上的全局变量。也许,麦当劳的实际数据库后端是建立在 Redis 之上的。事实上,您可以将 Redis 替换为您能想到的任何其他数据库,例如 MySQL、PostgresSQL 等。

这三者共同构成了一个任务排队系统。然后发生的是:

  1. 客户端与 Flask 应用程序对话以提出他们的请求。
  2. 应用程序接受请求,将其放入数据库队列(带有PENDING状态),以便 Celery 工作人员可以接受它们。客户端收到一个 JobID 并在旁边进行轮询。然后,该应用程序可以自由地接受下一个请求。
  3. Celery 工作人员接受请求并运行服务。
  4. 一旦工作人员完成,它会将作业的状态从 更新PENDINGSUCCESS
  5. 应用程序发出此更改的信号(或在轮询时返回),并且客户端看到他的请求现在已完成处理。拿到他的订单,继续他的快乐之路!

我忘了告诉你一件事

正如我们现在所知,Celery[2]充当了将上述所有组件组合在一起的框架。这包括您的 Flask 应用程序、数据库后端和工作人员。_我忘了告诉你_,还有一个重要的组件,消息队列

简而言之,您可以将其视为将这些服务连接在一起的波浪线。对于 Celery,可以充当消息队列的技术有 Redis、RabbitMQ、Memcache 等。您可以在此处查看技术列表[3]

真的只是 Flask、Celery 和 Redis 吗?

从我们的抽象领域,我们知道任务队列是解决问题的通用方法,我们只是替换(_switcheroo’d_)各种技术来完成这些角色。我们绝对可以为每个组件使用各种技术。例如,我们可以使用 MySQL 作为我们的数据库后端,使用 RabbitMQ 作为我们的消息队列。我们仍然实现相同的目标,只是使用了不同的技术。

结论

在本文中,我展示了 Flask、Celery 和 Redis 如何协同工作以形成任务队列。然后我们学到了以下内容:

  • 什么是任务队列以及为什么它对我们的系统很重要。
  • 任务队列的一般组件以及这些组件如何相互关联。
  • Flask、Celery 和 Redis 如何完成这些角色。

我们还了解到,像这样的系统需要一个消息队列(波浪线),并且可以在实现相同目标的同时将这些技术与其他框架切换。

以点麦当劳为例,说说为啥我们需要任务队列


注释

  1. ELI5:Explain like I’m five(像面对一个五岁的孩子那样跟我解释)的缩写。

  2. 在菲律宾语中, Ate的意思是姐姐,而Kuya的意思是哥哥。对于那些不是来自菲律宾的人,我们通常称每个人(甚至是我们的快餐服务人员)为哥哥姐姐。

  3. 这绝对是对客户所做工作的随意定义。在客户端-服务器架构中,有人提供资源或服务(服务器)和请求资源或服务的人(客户端)。

  4. 知识的诅咒 专家盲点(英语:Curse of knowledge),又称“知识的诅咒”,是一种认知偏差,指人在与他人交流的时候,下意识地假设对方拥有理解所需要的背景知识。Robin Hogarth 首先提出该名词 。专家盲点也是教育的重大阻碍之一。

原文:Distill: Why do we need Flask, Celery, and Redis? (with McDonalds in Between)[4]

参考资料

[1]

知识的诅咒: https://en.wikipedia.org/wiki/Curse_of_knowledge

[2]

Celery: http://www.celeryproject.org/

[3]

技术列表: http://docs.celeryproject.org/en/latest/getting-started/brokers/

[4]

Distill: Why do we need Flask, Celery, and Redis? (with McDonalds in Between): https://ljvmiranda921.github.io/notebook/2019/11/08/flask-redis-celery-mcdo/


原文始发于微信公众号(alitrack):以点麦当劳为例,说说为啥我们需要任务队列

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/62633.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!