2017-06-16 43 views
0

具有接收请求,生成数据并将其保存到文件中的数据的服务。 如果服务收到很多请求,可以尝试并行保存多达20个文件(每个服务器2个x 10个)。按要求生成并保存到S3 数据可以从几KB到大约〜400MBAWS S3 AmazonServiceException具有状态的WebException SecureChannelFailure

问题是有时候(好像是当服务正忙/大文件保存)S3失败与下面的异常: 我们讨论2解决方案:

1)如果保存失败,则执行S3.UploadAsync()的重试。 不知道是否会有所作为。假设S3已经在内部重试,所以也许没有必要重试。如果问题是文件过大/需要很长时间才能保存,则无法解决问题,可能会造成最坏的情况。

2)增加TransferUtilityConfig.DefaultTimeout为,例如10min(默认为5min)。 如果问题是保存时间超过5分钟,这将解决问题,但S3引发的异常并不表示是超时异常,所以这可能会解决任何问题。

3)这是AWS基础设施中的间歇性问题吗?可以重试帮助吗?

有没有人有这种异常发生时的经验/解决方案?任何其他想法?

更新: 如果使用NET 4.5,则TransferUtilityConfig()不包含DefaultTimeout。该功能已移至AmazonS3Config。这提供了更多的参数来控制上传:超时,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: 请求已中止:无法创建SSL/TLS安全通道。在 System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult的 asyncResult,TransportContext &上下文)在 System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult的 asyncResult)在 System.Threading.Tasks.TaskFactory 1.FromAsyncCoreLogic(IAsyncResult iar, Func 2 endfunction下面,动作1 endAction, Task 1承诺,布尔 requiresSynchronization)---从以前 位置的堆栈跟踪其中引发异常---结束在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务)在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 Amazon.Runtime.Internal.HttpHandler 1.<InvokeAsync>d__9 1.MoveNext() ---抛出异常的先前位置的堆栈跟踪结束---在 Amazon.Runtime.Internal.HttpHandler 1.<InvokeAsync>d__9 1。的MoveNext() ---从先前的位置在那里引发异常堆栈跟踪的结尾---在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)(任务 任务)在 Amazon.Runtime.Internal.RedirectHandler.d__1 1.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() ---在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess从先前的位置在那里引发异常---堆栈跟踪结束(任务 任务)在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 Amazon.S3.I nternal.AmazonS3ResponseHandler.d__1 1.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除外)在 Amazon.Runtime.Internal。 Amazon.Runtime.Internal.ErrorHandler.d__5 1.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() ---抛出异常的上一个位置的堆栈跟踪结束---在 系统。ErrorHandler.ProcessException(IExecutionContext executionContext,异常异常)at 系统。 Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务)在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务) Amazon.Runtime.Internal.CredentialsRetriever.d__7 1.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() ---从之前的位置抛出异常的堆栈跟踪结束---在 Amazon.Runtime.Internal.RetryHandler.d__10` 1.MoveNext()

回答

1

S3 SDK已经实现retry logic

默认情况下,上传retried 4 times

创建一个控制台应用程序,试图重现错误。控制台应用程序试图异步上传10-30个文件。更改AmazonS3Config for Timeout,ReadWriteTimeout,MaxErrorRetry中的值会产生异常(System.Net.WebException:操作已超时),但与我们所拥有的不一样(无法创建SSL/TLS安全通道)。

我们推测问题可能的服务是很忙,不能创建连接,这就是为什么得到“无法创建SSL/TLS安全通道”

1

这是一种古老的问题,但我的刚刚有一个非常类似的问题,因为我无法在Google上找到合适的答案,所以我想提供我的解决方案。

,我已经开始实施的旧的API,它有以下行:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; 

我能够通过改变SecurityProtocolType.Ssl3到SecurityProtocolType来解决此问题。Tls12


进一步解释:一般不支持

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的行并对其进行更正。