Обновить

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, временные доступы, обработка через очереди

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

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии2

Путь к ИИ‑сингулярности

У нас было два репозитория неоттестированного вайб‑кода, семьдесят пять тяжеловесных SDD‑спецификаций, пять обмазанных смазкой харнессов, солонка, наполовину полная кастомных скиллов и забитых капслоком правил, с десяток дырявых MCP‑серверов, RAG‑база со свежевекторизованным Confluence, самодельная дощечка имаго‑кодинга и целая россыпь автономных агентов всех мастей, от безобидных автодополнялок до галлюцинирующих субагентов, ставящих пакеты со slopsquatting и втихаря сносящих боевые базы.

Не то чтобы все это было действительно нужно для поездки к ИИ‑сингулярности, но если уж начали участвовать в спуске с горы на велосипеде без седла, остановиться уже невозможно.

Единственное, что вызывало у меня настоящий животный страх, это передача ответственности за ревью самой модели. Тот самый момент, когда седьмой агент подтверждает галлюцинации шестого, потому что все тесты зеленые, и я знал, что рано или поздно мы перейдем на эту дрянь.

Нет ничего более беспомощного, безответственного и испорченного, чем IT‑команда, запустившая мультиагентный оркестр в режиме allow all.

Это критический (и слегка ехидный) обзор того, что произошло с разработкой последние пару лет.

Путь к ИИ‑сингулярности

Публикации