【问题标题】:How to correctly queue image manipulation in laravel with beanstalkd while uploading to Amazon S3?如何在上传到 Amazon S3 时使用 beanstalkd 在 laravel 中正确排队图像操作?
【发布时间】:2015-06-25 14:16:09
【问题描述】:

我正在通过将图像加载到 Amazon S3 并使用 beanstalkd 对图像处理进行排队来使用 laravel 进行一些测试。请注意,这只是测试。

这是我的实现:

// 路由.php

Route::post('/', function()
{
    $validator = Validator::make(Input::all(), array(
        'title' => 'required',
        'file'  => 'required|mimes:jpeg,jpg,png',
    ));

    if( $validator->fails() )
    {
        return Redirect::to('/');
    }

    // Upload File
    $file = Input::file('file');

    $now = new DateTime;
    $hash = md5( $file->getClientOriginalName().$now->format('Y-m-d H:i:s') );
    $key = $hash.'.'.$file->getClientOriginalExtension();

    $s3 = AWS::createClient('s3');

    $s3->putObject(array(
        'Bucket'      => 'bellated',
        'Key'         => $key,
        'SourceFile'  => $file->getRealPath(),
        'ContentType' => $file->getClientMimeType(),
    ));

    // Create job
    Queue::push('\Proc\Worker\ImageProcessor', array(
        'bucket'   => 'bellated',
        'hash'     => $hash,
        'key'      => $key,
        'ext'      => $file->getClientOriginalExtension(),
        'mimetype' => $file->getClientMimeType(),
    ));

    Log::info('queue processed');

    return Redirect::to('/complete');
});

// 图像处理器

<?php namespace Proc\Worker;

use Imagine\Gd\Imagine;
use Imagine\Image\Box;

class ImageProcessor {

    protected $width;
    protected $height;
    protected $image;

    public function fire($job, $data)
    {
           $s3 = \AWS::createClient('s3');



        try {
   $response = $s3->getObject(array(
            'Bucket'      => $data['bucket'],
            'Key'         => $data['key'],
        ));
} catch (Exception $e) {
   return; 
}

        $imagine = new Imagine();
        $image = $imagine->load( (string)$response->get('Body') );

        $size = new Box(100, 100);
        $thumb = $image->thumbnail($size);

        $s3->putObject(array(
            'Bucket'      => 'bellated',
            'Key'         => $data['hash'].'_100x100.'.$data['ext'],
            'Body'        => $thumb->get($data['ext']),
            'ContentType' => $data['mimetype'],
        ));



    }

}

当我将“同步”作为队列时 - 一切正常,我在 Amazon 中获得了两个图像(原始图像和调整大小),但是在我切换到“beanstlakd”并运行 php artisan queue:listen 后,我不断收到此错误:

Next exception 'Aws\S3\Exception\S3Exception' 
  with message 'Error executing "GetObject" 
  on "https://s3.eu-central-1.amazonaws.com/bellated/cd05ec14f7a19047828d7ed79d192ee3.jpg";
 AWS HTTP error:  
 Client error: 404 NoSuchKey 
 (client): The specified key does not exist. - 
  <?xml version="1.0" encoding="UTF-8"?>
    <Error>
      <Code>NoSuchKey</Code>
      <Message>The specified key does not exist.</Message>
      <Key>cd05ec14f7a19047828d7ed79d192ee3.jpg</Key>
      <RequestId>9390AD2904820C3E</RequestId> 
      <HostId>
        nZK1ivZn3bs6xy0S/tGe+A7yoZgKKccLpUDObKuwS2Zmi8LXUgFI5JpkQWCkwchCw6tgW7jyvGE=
      </HostId>
    </Error>'
  in /home/vagrant/Code/laravel/vendor/aws/aws-sdk-php/src/WrappedHttpHandler.php:152

关于可能导致此问题的原因或我该如何继续此问题的任何想法?

【问题讨论】:

  • 你用的是什么版本的 laravel?
  • 5.1 - 我现在只需要了解如何调试或运行此控制台命令时有什么区别。

标签: laravel amazon-s3 beanstalkd


【解决方案1】:

您似乎正在将 s3 密钥设置为您的文件名,这可能会让您感到悲伤。

    $s3->putObject(array(
        'Bucket'      => 'bellated',
        'Key'         => $data['hash'].'_100x100.'.$data['ext'],
        'Body'        => $thumb->get($data['ext']),
        'ContentType' => $data['mimetype'],
    ));

这个错误让我想到了这个。

Client error: 404 NoSuchKey 
(client): The specified key does not exist. - 
<Key>cd05ec14f7a19047828d7ed79d192ee3.jpg</Key>

一般来说,您似乎正在努力做到这一点。我不确定如何让你的代码正常工作,但是 Laravel 做了很多你正在尝试做的事情。

这就是我如何完成你想要做的事情。

您需要设置环境。

.env

    S3_KEY=MYKEYMYKEYMYKEYMYKEY
    S3_SECRET=MYSECRETMYSECRETMYSECRETMYSECRETMYSECRET
    S3_REGION=us-east-1
    S3_BUCKET=bucketname

config/filesystem.php

    <?php
    return [
        'default' => 'local',
        'cloud' => 's3',
        'disks' => [
            'local' => [
                'driver' => 'local',
                'root'   => storage_path().'/app',
            ],
        's3' => [
            'driver' => 's3',
            'key'    => env('S3_KEY'),
            'secret' => env('S3_SECRET'),
            'region' => env('S3_REGION'),
            'bucket' => env('S3_BUCKET'),
        ],
        ],
    ];

routes.php快速测试

    Route::get('s3',function(){
        $success = Storage::disk('s3')->put('hello.txt','hello');
        return ($success)?'Yeay!':'Boo Hoo';
    });

我知道这是一个文本文件,但它是一样的。

我将如何处理队列是使用Laravel's Job(它曾经是命令)。

在终端类型会生成一个 app/Jobs/NewJob.php 文件。

php artisan make:job NewJob --queued

这样设置你的工作。

NewJob.php

    <?php

    namespace App\Jobs;

    use ...;

    class NewJob extends Job implements SelfHandling, ShouldQueue
    {
        public $content;
        public $path;

        use InteractsWithQueue, SerializesModels;
        public function __construct($content, $path)
        {
            $this->content = $content;
            $this->path = $path;
        }

        public function handle()
        {
            Storage::disk('s3')->put($this->path,$this->content)
        }
    }

你的控制器是这样的

    <?php

    namespace App\Http\Controllers;

    use ...;

    class ImageController extends Controller
    {
        public function sendImage($content, $path)
        {
            $this->dispatch(new NewJob($content, $path));
        }
    }

【讨论】:

    猜你喜欢
    • 2023-03-20
    • 2018-07-30
    • 2012-07-17
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 2015-06-17
    • 2017-04-28
    • 1970-01-01
    相关资源
    最近更新 更多