架构设计:网络层如何知道工作层何时完成处理?

Architecture design: how web-tier knows when worker-tier is done processing?

我正在使用 Amazon AWS 构建一个用于教育目的的小型应用程序。 Web 应用程序有两个部分:

  1. 上传图片的表单。
  2. 显示已上传图片的所有缩略图的网格。

申请流程:

  1. 用户打开网页。
  2. 用户选择要上传的图片。
  3. 已向 Web 层发送生成预签名 S3 URL 的 AJAX 请求。
  4. 收到URL后,发起AJAXPUT请求,图片直接上传到S3。
  5. 上传完成后,S3 发送带有图像密钥的 SQS 队列消息。
  6. 其中一名工作人员收到该消息并创建了缩略图。
  7. 图像处理完成后,工作人员将缩略图上传到 S3。

这张图说明了以上内容:


现在,Web 层使用 db.json 文件将 link 保存到所有现有缩略图。使用该文件,客户端网页呈现网格中的所有缩略图。

问题是,Web 层如何知道何时更新包含新缩略图 link 的 db.json

理想情况下,Web 层将完成以下任务:

  1. 仅在需要时刷新 json(如果 Web 层刷新了 json,则它必须已被修改)。
  2. 一旦更新 updated db.json(如果按时添加缩略图 x 并且另一个用户按时请求网页 x+1,则用户知道新缩略图)。

几种方法:

  1. 对于每个 index.html 请求,列出 S3 存储桶并提供最新的缩略图(违反上一节中的第 1 项)。

  2. 按时间间隔列出 S3 存储桶(违反两项)。

  3. 在请求预签名 URL 后设置计时器,并假设工作人员在计时器响起时已完成对新图像的处理(这甚至不是解决方案,主要有两个原因; Web 层有超过 1 个实例,计时器可能会在处理完成之前响起。

  4. 使用 S3 事件并设置一个 lambda 表达式,将 HTTP GET 请求发送到我的 Web 层上的一个特殊端点(也不是解决方案,因为此请求将从负载均衡器到单个实例,其他实例呢?)。


我不知道如何解决这个问题。 你建议我做什么?

编辑

由于这是一项教育练习,数据库服务不在范围内。

db.json 文件是否存储在其中一台网络服务器上?您如何协调跨多个 Web 服务器对 db.json 文件的更新?如何防止多个工作服务器同时更新 db.json 文件并相互踩踏?

我建议将缩略图存储在平面文件以外的地方。 DynamoDB 将是存储它的好地方。 PostgreSQL 或 RDS 上的 MySQL 风格之一也可以。

为了将 JSON 数据提供给包含缩略图列表的 UI,我将创建一个查询数据库并呈现 JSON 数据的动态页面。这也将允许您实现诸如数据分页之类的事情,一旦您的图像集变得非常大,这将是一个要求。

为了防止 Web 层因 JSON 数据请求而过载,我会在 Web 层前面放置一个 CDN,例如 CloudFront 或 CloudFlare。为了防止数据库因缩略图列表查询而过载,我将在 Web 层和数据库之间实现一个缓存层 (Redis)。

这个问题有点荒谬,将所有内容存储在我们不断更新的 JSON 文件中的概念,但解决方案似乎很明显......另一个 S3 事件通知。

任何时候你有一个系统可以给你神奇的事件礼物,让你不必轮询任何东西,你就不会忽视它带来的价值。

如果每个网络服务器都有自己的 json 文件副本并需要更新它,这也很容易解决。

创建缩略图时触发 S3 事件(S3 通知可以匹配前缀而不是针对整个存储桶)> S3 事件发布到 SNS 主题 > SNS 主题扇出到多个 SQS 队列,每个 Web 服务器一个。 Web 服务器上的进程使用单个线程订阅该服务器的队列,每次收到消息时,json 文件都会由本地工作者在该服务器上修改。每个服务器都会获得每个通知的副本。

我有一个旧的遗留系统,其中网站模板更改(不是代码,只是模板)是通过将模板更改提交到 subversion,然后在服务器上 svn up 来实现的。因为这个 subversion repo 的存在是为了这个目的,所以 Web 服务器直接从他的检出目录中读取模板。听起来很奇怪,但它已经使用了很多年。我最近通过设置一个让人想起上述内容但没有 S3 的安排来增强它。当提交任何内容时,"post-commit hook" 在颠覆服务器上触发一个 shell 脚本。这反过来又将有关已更改文件的消息发布到 SNS 主题,该主题扇出到多个 SQS 队列——一个用于每个 Web 服务器,每个服务器上的一个简单脚本侦听该服务器的 SQS 队列。每个服务器一个监听器,一个线程,因此不存在并发问题。侦听器,它在新提交的文件上运行 "svn up",删除队列消息,然后侦听下一个。实时事件扇出,为什么不呢?