拥有接收请求的服务,生成数据并将其保存在AWS S3的文件中。 如果服务收到许多请求,可以尝试并行保存多达20个文件(2个服务器x 10个工作者)。 请求生成并保存到S3的数据可以从几KB到约400MB
问题是有时(似乎是服务繁忙/要保存的大文件)S3失败,下面有例外: 我们讨论了两个解决方案:
1)如果保存失败,则执行S3.UploadAsync()的重试。 不确定是否会有所作为。假设S3已在内部重试,因此可能无需重试。如果问题是文件太大/需要很长时间来保存,这将无法解决问题可能会使它变得更糟。
2)将TransferUtilityConfig.DefaultTimeout增加到10分钟(默认为5分钟)。 如果问题是保存需要超过5分钟,这将解决问题,但S3抛出的异常并不表示是超时异常,所以这可能会解决任何问题。
3)这是AWS基础架构中的间歇性问题吗?可以重试一下吗?
当发生此异常时,是否有人有经验/解决方案?还有其他想法吗?
更新: 如果使用NET 4.5,TransferUtilityConfig()不包含DefaultTimeout。该功能已移至AmazonS3Config。这提供了更多参数来控制上传:Timeout,ReadWriteTimeout,MaxErrorRetry AmazonS3Config Class 这里解释了设置 AWS Retries and Timeouts
这是服务用于保存的代码:
using (var amazonS3Client = new AmazonS3Client(RegionEndpoint.GetBySystemName(_iAwsS3Settings.RegionEndpoint)))
using (var fileTransferUtility = new TransferUtility(amazonS3Client))
using (var memoryStream = new MemoryStream(data))
{
var fileTransferUtilityRequest = new TransferUtilityUploadRequest
{
BucketName = _iAwsS3Settings.BucketName,
InputStream = memoryStream,
StorageClass = S3StorageClass.ReducedRedundancy,
PartSize = 6291456, // 6 MB.
Key = fileLocation,
CannedACL = S3CannedACL.BucketOwnerFullControl
};
await fileTransferUtility.UploadAsync(fileTransferUtilityRequest, ct);
}
这是S3保存失败时的例外情况:
System.AggregateException:发生了一个或多个错误。 ---> Amazon.Runtime.AmazonServiceException:具有状态的WebException SecureChannelFailure被抛出。 ---> System.Net.WebException:The 请求已中止:无法创建SSL / TLS安全通道。在 System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult的 asyncResult,TransportContext&上下文) System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult的 asyncResult)at System.Threading.Tasks.TaskFactory
1.FromAsyncCoreLogic(IAsyncResult iar, Func
2 endFunction,Action1 endAction, Task
1 promise,Boolean requiresSynchronization)---来自之前的堆栈跟踪结束 抛出异常的位置--- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务) Amazon.Runtime.Internal.HttpHandler1.<InvokeAsync>d__9
1.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束--- at Amazon.Runtime.Internal.HttpHandler1.<InvokeAsync>d__9
1.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束--- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务) Amazon.Runtime.Internal.RedirectHandler.d__11.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Amazon.Runtime.Internal.Unmarshaller.<InvokeAsync>d__3
1.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束--- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务) Amazon.S3.Internal.AmazonS3ResponseHandler.d__11.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Amazon.Runtime.Internal.ErrorHandler.<InvokeAsync>d__5
1.MoveNext() ---内部异常堆栈跟踪的结束---在Amazon.Runtime.Internal.WebExceptionHandler.HandleException(IExecutionContext) executionContext,WebException异常)at Amazon.Runtime.Internal.ErrorHandler.ProcessException(IExecutionContext executionContext,异常异常)at Amazon.Runtime.Internal.ErrorHandler.d__51.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Amazon.Runtime.Internal.CallbackHandler.<InvokeAsync>d__9
1.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束--- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务) Amazon.Runtime.Internal.CredentialsRetriever.d__71.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Amazon.Runtime.Internal.RetryHandler.<InvokeAsync>d__10
1.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束--- at Amazon.Runtime.Internal.RetryHandler.d__10`1.MoveNext()
答案 0 :(得分:1)
S3 SDK已实现retry logic
默认情况下,上传为retried 4 times
创建一个控制台应用程序以尝试重现该错误。控制台应用程序尝试异步上载10-30个文件。更改AmazonS3Config中Timeout,ReadWriteTimeout,MaxErrorRetry的值会产生异常(System.Net.WebException:操作已超时)但与我们不一样(无法创建SSL / TLS安全通道)。
我们假设问题可能是服务太繁忙而无法创建连接,这就是为什么得到&#34;无法创建SSL / TLS安全通道&#34;
答案 1 :(得分:1)
这是一个古老的问题,但我遇到了一个非常类似的问题,因为我无法在Google上找到合适的答案,我想提供我的解决方案。
我已经开始实施旧API,其中包含以下行:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
我能够通过将SecurityProtocolType.Ssl3更改为SecurityProtocolType.Tls12
来解决此问题
进一步说明:
由于Poodle漏洞,通常不支持SSL3:
https://security.stackexchange.com/questions/70719/ssl3-poodle-vulnerability/70724#70724
我自己没有添加这行代码,因此,我很难找到问题的根源。但是,在研究我遇到类似问题时,我发现了这篇文章:https://github.com/aws/aws-sdk-net/issues/86
在本讨论的最后部分,有人建议添加以下行:
ServicePointManager.CheckCertificateRevocationList = true;
此修复程序无法纠正我的问题,但确实导致我走上了正确的道路。在搜索了对ServicePointManager的其他引用之后,我能够找到前面提到的有关SecurityProtocolType的行并进行更正。