Загрузка файла изображения занимает слишком много времени в AWS S3 c ++ SDK - PullRequest
1 голос
/ 11 июля 2019

Использование AWS S3 C ++ SDK для загрузки изображений .jpg определенному пользователю IAM приводит к большим задержкам, которые в любом случае вызваны сетевым трафиком и проблемами с задержкой. Я использую бесплатную версию S3 и 64-разрядную версию MSVC 2017 для своего приложения (на ПК с Windows 10). Вот пример кода:

Aws::SDKOptions options;
Aws::InitAPI(options);

Aws::Client::ClientConfiguration config;
config.region = Aws::Region::US_EAST_2;

Aws::S3::S3Client s3_client(Aws::Auth::AWSCredentials(KEY,ACCESS_KEY), config);

const Aws::String bucket_name = BUCKET;
const Aws::String object_name = "image.jpg";

Aws::S3::Model::PutObjectRequest put_object_request;

put_object_request.SetBucket(bucket_name);
put_object_request.SetKey(object_name);

std::shared_ptr<Aws::IOStream> input_data =
        Aws::MakeShared<Aws::FStream>("PutObjectInputStream",
                                      "../image.jpg",
                                      std::ios_base::in | std::ios::binary);

put_object_request.SetBody(input_data);
put_object_request.SetContentType("image/jpeg");

input_data->seekg(0LL, input_data->end);
put_object_request.SetContentLength(static_cast<long>(input_data->tellg()));

auto put_object_outcome = s3_client.PutObject(put_object_request);

Когда я загружаю изображения размером более 100 КБ, общая сумма

PutObject (put_object_request);

время выполнения превышает 2 минуты для изображения размером 520 КБ.

Я попробовал тот же пример с использованием Python boto3, и общее время загрузки для того же изображения составляет около 25 с.

Кто-нибудь сталкивался с такой же проблемой?

1 Ответ

0 голосов
/ 18 июля 2019

После лучшего взгляда на AWS github repo Я выясняю проблему.

Проблема заключалась в том, что WinHttpSyncHttpClient выполнял тайм-ауты и сбрасывал активность загрузки внутренне , таким образом, не выходя из потока загрузки и, наконец, прерывая транзакцию. Благодаря добавлению значения времени ожидания проблема решена.

Я использовал multipart Upload для повторной реализации примера, так как он кажется более надежным и управляемым. Хотя я думал, что он недоступен для C ++ SDK, это не так, поскольку TransferManager выполняет ту же работу для C ++ (не используя заголовки S3, как Java, .NET и PHP).

Спасибо KaibaLopez и SCalwas от репозитория AWS github, которые помогли мне решить проблемы ( issue1 , issue2 ). Я вставляю пример кода, если кто-то сталкивается с той же проблемой:

#include "pch.h"
#include <iostream>
#include <fstream>
#include <filesystem>

#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/Bucket.h>
#include <aws/transfer/TransferManager.h>
#include <aws/transfer/TransferHandle.h>

static const char* KEY = "KEY";
static const char* BUCKET = "BUCKET_NAME";
static const char* ACCESS_KEY = "AKEY";
static const char* OBJ_NAME = "img.jpg";
static const char* const ALLOCATION_TAG = "S3_SINGLE_OBJ_TEST";

int main()
{
    Aws::SDKOptions options;
    Aws::InitAPI(options);
    {
        Aws::Client::ClientConfiguration config;
        config.region = Aws::Region::US_EAST_2;
        config.requestTimeoutMs = 20000;

        auto s3_client = std::make_shared<Aws::S3::S3Client>(Aws::Auth::AWSCredentials(KEY, ACCESS_KEY), config);

        const Aws::String bucket_name = BUCKET;
        const Aws::String object_name = OBJ_NAME;
        const Aws::String key_name = OBJ_NAME;

        auto s3_client_executor = Aws::MakeShared<Aws::Utils::Threading::DefaultExecutor>(ALLOCATION_TAG);
        Aws::Transfer::TransferManagerConfiguration trConfig(s3_client_executor.get());
        trConfig.s3Client = s3_client;


        trConfig.uploadProgressCallback =
            [](const Aws::Transfer::TransferManager*, const std::shared_ptr<const Aws::Transfer::TransferHandle>&transferHandle)
        { std::cout << "Upload Progress: " << transferHandle->GetBytesTransferred() <<
            " of " << transferHandle->GetBytesTotalSize() << " bytes" << std::endl;};

        std::cout << "File start upload" << std::endl;

        auto tranfer_manager = Aws::Transfer::TransferManager::Create(trConfig);
        auto transferHandle = tranfer_manager->UploadFile(object_name.c_str(),
            bucket_name.c_str(), key_name.c_str(), "multipart/form-data", Aws::Map<Aws::String, Aws::String>());

        transferHandle->WaitUntilFinished();

        if(transferHandle->GetStatus() == Aws::Transfer::TransferStatus::COMPLETED)
            std::cout << "File up" << std::endl;
        else
            std::cout << "Error uploading: " << transferHandle->GetLastError() << std::endl;
    }
    Aws::ShutdownAPI(options);
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...