我正在用laravel做一些测试,将图像加载到AmazonS3,并用beanstalkd排队处理图像。请注意,这只是测试。
这是我的实现:
//routes.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('ProcWorkerImageProcessor', array(
'bucket' => 'bellated',
'hash' => $hash,
'key' => $key,
'ext' => $file->getClientOriginalExtension(),
'mimetype' => $file->getClientMimeType(),
));
Log::info('queue processed');
return Redirect::to('/complete');
});
//图像处理器
<?php namespace ProcWorker;
use ImagineGdImagine;
use ImagineImageBox;
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'],
));
}
}
当我将"sync"作为队列时,一切都很好,我在亚马逊中获得了两个图像(原始图像和调整大小的图像),但在我切换到"beanstlakd"并运行php artisan队列后:听着,我一直收到这个错误:
Next exception 'AwsS3ExceptionS3Exception'
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
有什么想法可能导致这种情况,或者我该如何处理?
看起来您正在将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/files系统.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的工作(它过去是命令)。
在终端上键入将生成app/Jobs/NewJob.php文件的类型。
php artisan make:job NewJob --queued
这样安排你的工作。
NewJob.php
<?php
namespace AppJobs;
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 AppHttpControllers;
use ...;
class ImageController extends Controller
{
public function sendImage($content, $path)
{
$this->dispatch(new NewJob($content, $path));
}
}