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

时间:2016-04-26 19:42:30

标签: amazon-web-services amazon-s3 architecture

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

  1. 上传图片的表单。
  2. 显示已上传图片的所有缩略图的网格。
  3. 申请流程:

    1. 用户打开网页。
    2. 用户选择要上传的图片。
    3. 发送对Web层的AJAX请求以生成预先签名的S3 URL。
    4. 收到URL后,会启动AJAX PUT请求,并将图像直接上传到S3。
    5. 上传完成后,S3会发送带有图像密钥的SQS队列消息。
    6. 其中一名工作人员收到该消息并创建缩略图。
    7. 图像处理完成后,工作人员将缩略图上传到S3。
    8. 这个图说明了上述情况: enter image description here

      现在,Web层使用db.json文件来保存指向所有现有缩略图的链接。使用该文件,客户端网页呈现网格中的所有缩略图。

      问题是,网络层如何知道何时更新包含新缩略图链接的db.json

      理想情况下,网络层将实现以下目标:

      1. 仅在需要时刷新json(如果网络层刷新了json,那么它必须已被修改)。
      2. 更新已更新 db.json(如果按时添加了缩略图x而另一位用户按时请求了网页{{1}然后用户知道新的缩略图。)
      3. 很少接近:

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

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

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

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

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

          修改

          由于这是一项教育活动,因此数据库服务超出了范围。

2 个答案:

答案 0 :(得分:1)

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

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

要将JSON数据提供给包含缩略图列表的UI,我将创建一个查询数据库并呈现JSON数据的动态页面。这也可以让你实现数据分页之类的事情,一旦你的图像集非常大,这将是一个要求。

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

答案 1 :(得分:1)

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

任何时候你有一个系统可以为你提供神奇的事件礼物,让你无需进行任何投票,你就会忽视它带来的价值。

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

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

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