1

手头的问题

  1. 我有一个轨道应用程序。
  2. 用户将上传文件。1 个文件到 3000 个文件之间的任何位置。有时它们是 zip 文件,有时它们不是。我不想通过这些文件上传来阻止服务器,所以我正在寻找解决这个问题的方法。
  3. 压缩文件必须解压缩。
  4. 然后我想检查是否:用户以前上传过相同的文件?即如果用户已经在一周前上传了相同的文件(2),那么这是一个问题:(i) 我们不允许上传该特定文件,或者我们询问用户:你确定你想要再次上传相同的文件?
  5. 然后我想在后端的适当模型/记录中存储文件的键/链接。

想知道处理上述问题的最佳工作流程是什么:即一个非常笼统的概述:换句话说,AWS Lambda / Google 云计算等是否可以最好地用于处理上述问题?我们将如何使用神殿宝石来最好地处理这种情况?使用 AWS Lambda 而不是使用后台作业有意义吗?

我的偏好是使用 Shrine gem 进行上传。

我的想法:

  1. 在客户端,用户拖放用户想要上传的文件。
  2. 然后通过 Shrine gem 将所有文件上传(无论是压缩文件还是其他文件)到临时存储桶位置。
  3. 如果上传了 zip 文件,则可能必须触发 AWS lambda 函数来解压缩文件。如果是这种情况,那么最终,这些文件的密钥必须以某种方式返回给客户端,以处理验证问题——但是 AWS lambda 函数如何能够将此请求返回给原始客户端请求是从哪里发起的?或者更确切地说,是否应该从客户端生成 AWS lambda 函数,并传入解压缩 blob 的 ID?
  4. 然后我们需要运行一些验证:我们要处理存在重复文件的情况。我们需要检查我们支持的 Rails 是否已经上传了这些文件。
  5. 处理完这些验证问题后,用户提交表单,所有密钥都存储在适当的记录中。

这些想法绝不是规定性的

我正在寻求一些非常普遍的建议,说明什么是做这一切的最佳方式。我绝不会受限于 AWS:我可以同样轻松地使用 Google 或 Azure。任何关于上述内容的指导将不胜感激。

具体问题:

  1. AWS lambda 函数将如何被触发?
  2. 如何将上传文件的密钥返回给客户端?

一般概述是什么意思?

以下是一些一般概述的示例:

(1)通过 Heroku 上的 Rails 上传和解压文件到 S3?

(2) https://www.quora.com/How-do-I-extract-large-zip-files-in-AWS-Lambda

任何指向正确方向的指针都将不胜感激。

干杯!

4

1 回答 1

1

如果您愿意稍微改变一下流程,这并不是一个很难解决的问题。

在客户端,用户拖放用户想要上传的文件。

当用户请求开始上传操作时,您可以向 API Gateway 端点发出 HTTP GET 请求,并由 Lambda 提供支持。Lambda 可以查询客户端之前上传的文件,并返回一个结果集,显示哪些文件已经存在。然后,您将它们过滤掉并仅将认为是新的内容从客户端发送到服务器。这将节省用户等待上传的时间,并节省您在 S3/Lambda 方面的时间,而不必存储重复项或处理它们。但是,这不能替代服务器端验证,您仍然希望这样做。对于合法客户,这将为您和他们节省大量带宽和存储空间。

然后通过 Shrine gem 将所有文件上传(无论是压缩文件还是其他文件)到临时存储桶位置。

这行得通。当他们进入临时存储桶时,使用带有 S3 事件的 Lambda来处理文件、解压缩文件、将所需的任何元数据推送到 DynamoDb 并从临时存储桶中删除文件。在临时存储桶中,我会将文件放入每个请求和用户唯一的文件夹中。我会使用用户/客户端 ID 和某种 UUID 并将其设为您的文件夹名称。例如Johnathon+3b5339b8-c8db-4d5c-b678-406fcf073f4f,或将此值编码为 Base64 字符串并将其设为您的文件夹名称。将其存储在 DynamoDb 中,并将每个文件上传到您的永久存储桶中,哈希键是用户 ID/客户端 ID,排序键是完整文件夹路径 + 文件名和IsProcessed. 这IsProcessed属性将由正在处理文件并将它们移动到其永久 S3 存储桶的 Lambda 更新。如果有错误,您可以将错误放在此字段中。如果成功,则将其放在此字段中。

这些文件的密钥必须以某种方式返回给客户端,以处理验证问题——但是 AWS lambda 函数如何能够将此请求返回到发起请求的原始客户端?或者更确切地说,是否应该从客户端生成 AWS lambda 函数,并传入解压缩 blob 的 ID?

将文件推送到临时 S3 存储桶的原始 API 请求将能够将文件夹名称返回给johnathon+3b5339b8-c8db-4d5c-b678-406fcf073f4f客户端。因此,假设您向/jobs. 您将返回201 Created一个Location /jobs/johnathon+3b5339b8-c8db-4d5c-b678-406fcf073f4f. 然后,您的客户端可以开始轮询/jobs/johnathon+3b5339b8-c8db-4d5c-b678-406fcf073f4f进程的状态。

您的回复/jobs/johnathon+3b5339b8-c8db-4d5c-b678-406fcf073f4f可以返回 DynamoDB 记录。这将包括与文件夹名称匹配的 HashKey 的所有 DynamoDB 记录。您的客户端可以查看结果集中的所有对象并检查IsProcessed属性以查看是否一切正常,或者是否存在问题。

然后我们需要运行一些验证:我们要处理存在重复文件的情况。我们需要检查我们支持的 Rails 是否已经上传了这些文件。

使用临时存储桶执行的 Lambda 处理此问题。从临时存储桶文件夹中获取文件,处理您的业务逻辑和后端查询,然后将它们推送到最终的永久存储桶。

处理完这些验证问题后,用户提交表单,所有密钥都存储在适当的记录中。

所有这些都将异步发生,从用户提交表单开始。客户端需要能够通过向上述端点发出 HTTP GET 请求来处理这个问题,检查进程的状态。这为您提供了更大的灵活性,因为您还可以在失败时发布 SNS 消息,例如如果客户上传了 3,000 个文件并且您需要花费 30 分钟处理它们,则向他们发送电子邮件。

于 2019-12-17T02:03:15.923 回答