首页 > 解决方案 > 将文件上传到 S3 并将元数据上传到 RDS 的最佳实践?

问题描述

语境

我正在构建一个模拟服务来学习 AWS。我希望用户能够上传声音文件(其他用户可以收听)。为此,我需要将声音文件上传到 S3 和元数据,例如文件名、上传者名称、长度、S3 ID 到 RDS。最好用户使用签名 URL 直接上传到 S3,而不是通过首先将数据上传到我的服务器并从那里到 S3 来使传输的数据翻倍。

最佳情况下,这将是事务性的,但从我收集的内容来看,没有给定的功能。为了实现这一点并最大程度地降低文件成功上传到 S3 而不是元数据到 RDS 的风险,反之亦然,我最好的猜测如下:

我的解决方案

用词:首先是尝试使用我在本地或服务器端生成的密钥(uuid)将文件上传到 S3。如果这成功了,我会向我的 API 发出请求以上传元数据,包括 RDS 的密钥。如果这不成功,我会从 S3 中删除该对象。

带代码:

uuid = get_uuid_from_server(); 
s3Client.putObject({.., key: uuid, ..}, function(err, data) {
   if (err) {
    reject(err);
   } else {
    resolve(data);
    // Upload metadata to RDS through API-call to EC2 server. Remove s3 object with key: 
       uuid if this call is unsuccessful
   }
  });

在我学习的过程中,我的方法很少是最佳实践,但我找不到关于这个特定问题的任何好的信息。我上面的方法/解决方案是否符合最佳实践?

额外的问题:在服务器端而不是客户端生成文件的密钥(uuid)是否有利于安全目的?

标签: amazon-web-servicesamazon-s3amazon-rds

解决方案


假设客户端是 Web 浏览器或移动应用程序,您可以选择以下 2 种方法。

1. 使用您的服务器作为 S3 的代理。

您的服务器充当客户端和 S3 之间的代理,您可以完全控制上传流程、控制支持的文件类型并可以检查文件内容,例如:在上传到 S3 之前确保文件是正确的声音文件.

2. 使用您的服务器创建预签名的上传 URL

在这种方法中,您的客户端首先请求服务器创建一个或多个(用于分段上传)预签名 URL。然后客户端使用这些 URL 上传到您的 S3。您的服务器可以保存这些 URL 以便以后跟踪。

要在上传成功或失败时收到通知,您可以

(1) 要求客户端调用另一个 API,例如:在上传完成后为特定签名 URL调用/ack 。如果一段时间后没有调用此 API,例如:1 小时,您可以检查 S3 并相应地删除文件。您可以这样做,因为您在上传开始时已将签名 URL 存储在您的数据库中。

或者

(2) 利用S3 事件。您可以在 S3 中配置 ObjectCreated 事件,该事件在创建对象时触发,并将所有事件发送到 SQS 中的队列,并让您​​的服务器从那里处理每个事件。这样,您就不必依赖客户端在上传完成后更新您的服务器。对于所有成功的上传,S3 将相应地通知您的服务器。


推荐阅读