提供一个服务接收请求,生成数据并将其保存在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类 设置在此处解释 AWS重试和超时
这是服务用于保存的代码:
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: 请求已中止:无法创建 SSL/TLS 安全通道。 at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context) at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult) at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func
2 endFunction, Action1 endAction, Task
1 promise, Boolean requiresSynchronization) --- 在引发异常的上一个位置结束的堆栈跟踪 --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at
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(Task task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at
Amazon.Runtime.Internal.RedirectHandler.d__11.MoveNext()
--- 在引发异常的上一个位置结束的堆栈跟踪 --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at
Amazon.Runtime.Internal.Unmarshaller.<InvokeAsync>d__31.MoveNext()
--- 在引发异常的上一个位置结束的堆栈跟踪 --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at
Amazon.S3.Internal.AmazonS3ResponseHandler.d__11.MoveNext()
--- 在引发异常的上一个位置结束的堆栈跟踪 --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at
Amazon.Runtime.Internal.ErrorHandler.<InvokeAsync>d__51.MoveNext()
--- 结束内部异常堆栈跟踪 --- at Amazon.Runtime.Internal.WebExceptionHandler.HandleException(IExecutionContext executionContext, WebException exception) at
Amazon.Runtime.Internal.ErrorHandler.ProcessException(IExecutionContext executionContext, Exception exception) at
Amazon.Runtime.Internal.ErrorHandler.d__51.MoveNext()
--- 在引发异常的上一个位置结束的堆栈跟踪 --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at
Amazon.Runtime.Internal.CallbackHandler.<InvokeAsync>d__91.MoveNext()
--- 在引发异常的上一个位置结束的堆栈跟踪 --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at
Amazon.Runtime.Internal.CredentialsRetriever.d__71.MoveNext()
--- 在引发异常的上一个位置结束的堆栈跟踪 --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at
Amazon.Runtime.Internal.RetryHandler.<InvokeAsync>d__101.MoveNext()
--- 结束在引发异常的上一个位置的堆栈跟踪 --- at
Amazon.Runtime.Internal.RetryHandler.d__10`1.MoveNext()