Search
Write a publication
Pull to refresh

Multipart Upload в Laravel: загрузка больших файлов в S3

Что такое Multipart Upload и зачем он нужен?

Multipart Upload - это метод загрузки больших файлов в S3, при котором файл разбивается на части (чанки) и загружается параллельно. Это решает несколько ключевых проблем:

  1. Надёжность - при обрыве соединения можно перезагрузить только failed-часть

  2. Производительность - параллельная загрузка частей ускоряет процесс

  3. Обход ограничений - позволяет загружать файлы больше 5 ГБ (максимальный размер для простой загрузки)

Как реализовать Multipart Upload в Laravel

1. Установка зависимостей

Убедитесь, что у вас установлен AWS SDK (обычно идёт с Laravel):
composer require aws/aws-sdk-php

2. Пример реализации

 use Illuminate\Http\UploadedFile;
 use Aws\S3\MultipartUploader;
 use Aws\Exception\MultipartUploadException;



private function uploadFileToS3(UploadedFile $file, string $fileName): string
 {
 // Получаем клиент S3 из Storage фасада
$client = Storage::disk('s3')->getClient();
// Путь для сохранения в S3 (можно добавить подпапки по дате и т.д.)
$s3Path = $this->s3path.'/'.$fileName;

// Настройки загрузчика
$uploader = new MultipartUploader($client, $file->getPathname(), [
    'bucket' => config('filesystems.disks.s3.bucket'),
    'key'    => $s3Path,
    'part_size' => 5 * 1024 * 1024, // 5 MB за часть чанка
    'concurrency' => 3, // Количество параллельных загрузок
    'before_initiate' => function ($command) {
        // Можно добавить метаданные или ACL
        $command['ACL'] = 'public-read';
    },
    'before_upload' => function ($command) {
        // Логирование перед загрузкой каждой части
        Log::info('Uploading part', [
            'part_number' => $command['PartNumber'],
            'upload_id' => $command['UploadId']
        );
    },
]);

try {
    // Запускаем процесс загрузки
    $result = $uploader->upload();
    
    // Возвращаем полный путь к файлу в S3
    return $s3Path;
    
} catch (MultipartUploadException $e) {
    // Логируем ошибку
    Log::error('Multipart upload failed', [
        'file' => $fileName,
        'error' => $e->getMessage(),
        'upload_id' => $e->getUploadId()
    ]);
    
    // Можно попробовать возобновить загрузку
    // $this->resumeUpload($e->getUploadId(), $s3Path);
    
    throw new \Exception('File upload failed: '.$e->getMessage());
}
}

3. Дополнительные методы для работы с Multipart Upload

Возобновление прерванной загрузки

private function resumeUpload(string $uploadId, string $s3Path): string
 {

$client = Storage::disk('s3')->getClient()
$uploader = new MultipartUploader($client, null, [
    'bucket' => config('filesystems.disks.s3.bucket'),
    'key'    => $s3Path,
    'upload_id' => $uploadId,
    'part_size' => 5 * 1024 * 1024,
]);

try {
    $result = $uploader->upload();
    return $s3Path;
} catch (MultipartUploadException $e) {
    throw new \Exception('Resume upload failed: '.$e->getMessage());
}
}

Когда использовать Multipart Upload

  1. Файлы больше 100 МБ - для меньших файлов обычная загрузка может быть эффективнее

  2. Ненадёжные соединения - где возможны обрывы

  3. Критичные по времени загрузки - когда нужно максимально ускорить процесс

Оптимизация параметров

  • part_size:

    • 5-10 MB - хороший баланс для большинства случаев

    • Увеличивайте для очень больших файлов (>1 GB)

  • concurrency:

    • 3-5 - оптимально для большинства случаев

    • Можно увеличить для очень быстрых соединениях

Что ждёт в следующих статьях?

🔹 Ограничения PHP при работе с файлами (максимальный размер загрузки, timeout-ы, memory_limit)
🔹 Глубокий разбор S3 — Versioning, Lifecycle Policies, Cross-Region Replication
🔹 Продвинутое потоковое чтение/запись — обработка гигабайтных логов, CSV и медиа без нагрузки на память
🔹 CDN-оптимизация — Geo-DNS, кеширование, пресеты для изображений
🔹 Секретные фишки — Signed URLs, временные доступы, обработка через очереди

Остались вопросы или есть темы, которые хотите разобрать подробнее? Пишите в комментариях — ваши пожелания станут основой для следующих статей!

Tags:
Total votes 1: ↑1 and ↓0+1
Comments2

Articles