跳到正文

消息队列

Message Queue

高级通用

消息队列(Message Queue)是让一个程序先发送消息、由另一个程序稍后取出处理的中间通道。它能把耗时任务从当前请求中拆出去,也能缓冲突发任务;例如用户上传文件后,后台再生成缩略图。

你可能会说:「用户上传文件后,我想先让页面返回结果,缩略图在后台慢慢生成,怎么做?」

读之前建议先了解(这是一个高级概念)

动手看看

生成任务上传请求消息队列等待处理后台程序缩略图存储
1

图片上传完成后,请求只把“生成缩略图”的任务消息送进队列,不在这里做耗时处理。

要点

  1. 1

    发送方先把任务写成消息

    比如用户上传文件后,网站把文件 ID 放进消息队列,再告诉用户「已收到」。这样当前请求不必等缩略图生成完;但「已收到」只代表任务已交出去,不代表缩略图已经可用。

  2. 2

    消费者取出消息执行任务

    另一个后台程序作为消费者,从队列取出文件 ID,找到原文件并生成缩略图。我们可以把它单独运行和扩容,所以图片处理变慢时,不必让上传接口跟着一直等待。

  3. 3

    失败处理要从一开始想清楚

    消费者处理成功后通常会确认消息;如果处理失败,消息可能再次被取出。因为同一任务可能执行多次,所以生成结果最好能重复写入而不出错,同时要能查看失败记录,避免任务悄悄卡住。

容易混淆的地方

消息队列不是数据库:数据库主要保存供查询和更新的数据,队列主要传递待处理的消息,不能把「消息已发送」当成业务结果已写入。它也不是普通的同步 API 调用:同步调用通常要等对方返回结果,而用队列时,发送方和消费者可以在不同时间工作;如果页面马上需要处理结果,光靠队列解决不了。

什么时候用

适合用

  • 用户上传视频后先返回接收结果,再让后台转码,页面通过任务状态显示后续进度。
  • 订单创建后,把发送确认邮件交给后台处理,避免邮件服务变慢拖住下单响应。
  • 活动开始时大量用户提交报表生成请求,先排队,再由有限数量的后台程序逐步处理。

不适合用

  • 页面打开时只需读取一条商品详情,并且马上展示结果,直接查询数据库或调用同步 API 更合适。
  • 用户提交表单后必须立刻知道字段是否合规,直接在请求中校验并返回错误,排队处理会让反馈太晚。
  • 只是想在同一个进程里延后执行一个很短的界面操作,用本地调度机制即可,不必引入消息队列。

练一练

你在做一个视频上传网站。转码有时要几分钟,用户上传完成后可以稍后再看视频。怎样设计上传后的处理流程?

让 AI 帮你做

请为视频上传功能设计消息队列处理流程:原文件保存后发送转码消息,接口只返回任务 ID 和已接收状态;由消费者转码并更新任务状态。请说明失败重试、重复消息处理和页面如何查询结果,不要把入队成功当作转码成功。

接下来学什么