【问题标题】:PHP Laravel Uploading File to AWS S3 AsyncronousPHP Laravel 将文件上传到 AWS S3 异步
【发布时间】:2018-07-03 01:40:09
【问题描述】:

我正在使用 AWS S3 实现上传文件。我要上传的文件平均为 500 Mb。上传过程(使用文件系统 AWS S3)是同步的。因此,当一个用户上传大文件时,其他人在用户完成上传进度之前无法访问该网站。如何使其异步?

基本上,我有两个问题:

  1. 分块上传大文件,以便其他人可以使用该网站
  2. 异步上传。

我用来处理上传的命令是:

Storage::put('preview_image/'.$file_name, $file_preview_image_1, 'public');

【问题讨论】:

    标签: php laravel amazon-s3


    【解决方案1】:

    为什么不使用推荐用于大于 100MB 的文件的异步分段上传? 代码将如下所示:

    $source = '/path/to/large/file.zip';
    $uploader = new MultipartUploader($s3Client, $source, [
        'bucket' => 'your-bucket',
        'key'    => 'my-file.zip',
    ]);
    
    $promise = $uploader->promise();
    

    您可以在此处查看文档:Asynchronous multipart uploads

    【讨论】:

      【解决方案2】:

      已解决

      纠结了好几天,一直在寻找一个好的解决方案,我终于明白了为什么我的项目是单线程的,因为我跑了php artisan serve。我在https://github.com/laravel/framework/issues/22944 上报告了问题。

      【讨论】:

        【解决方案3】:

        我不明白为什么其他用户无法访问该网站,因为现代服务器能够很好地处理多个请求,也许您必须考虑升级您的服务器。

        但是要在您的项目中具有异步行为,您可以查看 laravel Jobs and Queues,这是文档 link,但是您必须考虑适当更改队列驱动程序,默认情况下 laravel 队列驱动程序是 sync 这是只有同步,一旦你设置了队列,它可以是redis队列或amazon sqs或任何东西,你可以将文件上传作业推送到队列,你可以让用户摆脱等待文件上传的麻烦,那里是像laravel horizon 这样的自定义包,用于监控您的队列。如果作业失败,您甚至可以在其中重新启动作业。

        【讨论】:

        • "我不明白为什么其他用户无法访问该网站....." -> 所以,当用户上传文件时,他们会直接向 AWS S3 存储发送文件请求。由于文件太大,“请求”的进度需要太多时间。谢谢你的回答:)
        【解决方案4】:

        处理需要花费过多时间(超过 5 秒)才能完成的作业时,经验法则是在后台处理它们。

        见:https://laravel.com/docs/5.5/queues

        所以当一个用户上传大文件时,其他人在用户完成上传进度之前无法访问该网站

        但是你的问题是你的上传带宽被上传完全消耗了运行上传过程的 php 脚本消耗了太多的内存,因此阻止了其他 php 线程的产生.

        【讨论】:

        • 如果我在后台处理上传文件,如果用户关闭浏览器呢?
        • 阅读完您的cmets后,首先您必须解决上传文件时用户停留在同一页面的问题。您应该查看单页应用程序 (SPA) 以对前端进行编码,例如:React、AngularJs。
        • 感谢 SPA,我正在寻找。 :)
        【解决方案5】:

        如果您尝试将文件从用户磁盘上传到远程位置,则无法执行您想要的操作(即排队等待稍后完成)。

        用户需要在表单的$POST请求中完成文件上传——你不能queue稍后再完成。排队是为了延迟服务器端处理任务并稍后完成 - 但上传需要用户留在页面上以send 将数据发送到您的服务器。

        为了进一步扩展——你能做的最好的选择是一个javascript异步上传——使用像dropzonejs这样的包。这样,用户可以同时上传多个文件,并获得视觉进度条更新。

        【讨论】:

        • "上传需要用户停留在页面上才能将数据发送到您的服务器" -> 这也是问题,所以当用户退出浏览器时(但上传文件的进度尚未开始)然后上传进度将失败。顺便说一句,感谢您的 asnwer 和 dropzonejs :)
        • @fird0s 是的,这就是它的要点
        • 我在考虑先在本地上传,然后运行队列从本地上传到 AWS S3。你觉得怎么样?
        • @fird0s 不能解决您试图绕过的问题,用户将不得不等待相同的时间,直到上传完成在这两种情况下,对吧?我建议您坚持使用 s3 并使用 js 库进行异步上传,这至少可以为用户提供有关进度的视觉反馈。
        • @fird0s 还记得在使用s3 上传时要分块,以免在上传期间内存不足。由于 php 在上传文件时会尝试将整个文件加载到内存中,这很容易阻塞您的服务器以进行大尺寸上传
        猜你喜欢
        • 2020-10-10
        • 2016-04-07
        • 2020-09-25
        • 1970-01-01
        • 1970-01-01
        • 2018-09-30
        • 2021-05-11
        • 2021-02-07
        • 2010-10-14
        相关资源
        最近更新 更多