Ubuntu 20.04多线程VM中AWS C++ SDK调用S3 GetObject超时错误
AWS SDK for C++多线程获取S3对象Ubuntu虚拟机超时问题(curlCode 28)
问题现象
- Windows环境下多线程调用S3
GetObject接口完全正常 - VMware Workstation Player 16搭建的Ubuntu 20.04虚拟机中,单线程运行正常,线程数>1时,运行一段时间后触发curl错误码28(超时)
- 已调整超时参数至120秒、修改重试策略,均无效;数据集规模庞大,无法通过单纯延长超时解决
核心代码片段:
const auto objectsReq = Aws::S3::Model::GetObjectRequest() .WithBucket(bucket) .WithKey(key); auto objectsResp = s3Client->GetObject(objectsReq); // 错误发生在此处 if (!objectsResp.IsSuccess()) return objectsResp.GetError().GetExceptionName();
超时配置:
Aws::Client::ClientConfiguration clientCfg; clientCfg.httpRequestTimeoutMs = 120'000l; clientCfg.connectTimeoutMs = 120'000l; clientCfg.requestTimeoutMs = 120'000l;
重试策略配置:
auto retryStrategy = std::make_shared<Aws::Client::StandardRetryStrategy>(5l); clientCfg.retryStrategy = retryStrategy;
日志分析
从AWS调试日志可见关键异常:
[DEBUG] 2022-08-31 14:43:19.481 CURL [140673617475328] (Text) Connection timeout after 30000 ms [ERROR] 2022-08-31 14:43:19.481 CurlHttpClient [140673617475328] Curl returned error code 28 - Timeout was reached
矛盾点:代码设置120秒超时,但实际触发30秒超时,说明超时参数未正确生效;同时多线程环境下curl连接池或网络配置存在瓶颈。
解决方法
1. 强制生效超时参数
代码中使用的单引号数字格式(120'000l)在部分编译器下可能解析异常,同时需手动设置curl底层选项确保超时生效:
Aws::Client::ClientConfiguration clientCfg; // 改用标准数字格式 clientCfg.httpRequestTimeoutMs = 120000; clientCfg.connectTimeoutMs = 120000; clientCfg.requestTimeoutMs = 120000; // 直接设置curl底层超时选项 clientCfg.curlOptions.emplace_back(CURLOPT_CONNECTTIMEOUT_MS, 120000L); clientCfg.curlOptions.emplace_back(CURLOPT_TIMEOUT_MS, 120000L);
2. 扩容curl连接池
AWS SDK C++默认curl连接池大小有限,多线程下会出现连接等待超时,需手动调整全局连接数:
Aws::SDKOptions apiOptions; Aws::InitAPI(apiOptions); // 根据并发线程数调整,建议设置为线程数的1.5-2倍 Aws::Http::CurlHttpClient::SetGlobalMaxConnections(64); auto s3Client = Aws::MakeShared<Aws::S3::S3Client>("S3Client", clientCfg);
3. 禁用IPv6优先
虚拟机IPv6配置可能存在异常,导致curl优先尝试IPv6连接失败,强制使用IPv4:
clientCfg.curlOptions.emplace_back(CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
4. 调整VMware网络配置
- 将虚拟机网络适配器从NAT模式切换为桥接模式,避免NAT的并发连接限制
- 若使用NAT模式,编辑VMware NAT配置文件(
/etc/vmware/nat.conf),增大max_connections参数
5. 升级AWS SDK C++版本
当前使用的1.9.160版本存在多线程下curl连接池的已知bug,升级至最新稳定版(如1.11.x及以上)可修复此类问题。
6. 控制并发请求数
根据虚拟机CPU核心数和网络带宽限制并发线程数,避免触发S3请求速率限制或虚拟机网络瓶颈(例如4核虚拟机设置8-12个并发线程)。
内容的提问来源于stack exchange,提问作者Dmitrii
相关产品推荐
相关产品推荐

