AWS S3 AmazonServiceException状态为SecureChannelFailure

时间:2017-06-16 10:20:39

标签: c# amazon-web-services amazon-s3

拥有接收请求的服务,生成数据并将其保存在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:发生了一个或多个错误。 ---&GT;   Amazon.Runtime.AmazonServiceException:具有状态的WebException   SecureChannelFailure被抛出。 ---&GT; System.Net.WebException:The   请求已中止:无法创建SSL / TLS安全通道。在   System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult的   asyncResult,TransportContext&amp;上下文)   System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult的   asyncResult)at   System.Threading.Tasks.TaskFactory 1.FromAsyncCoreLogic(IAsyncResult iar, Func 2 endFunction,Action 1 endAction, Task 1 promise,Boolean   requiresSynchronization)---来自之前的堆栈跟踪结束   抛出异常的位置--- at   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)   Amazon.Runtime.Internal.HttpHandler 1.<InvokeAsync>d__9 1.MoveNext()   ---从抛出异常的先前位置开始的堆栈跟踪结束--- at   Amazon.Runtime.Internal.HttpHandler 1.<InvokeAsync>d__9 1.MoveNext()   ---从抛出异常的先前位置开始的堆栈跟踪结束--- at   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()   ---从抛出异常的先前位置开始的堆栈跟踪结束--- at   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务   任务)   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)   Amazon.S3.Internal.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异常)at   Amazon.Runtime.Internal.ErrorHandler.ProcessException(IExecutionContext   executionContext,异常异常)at   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()   ---从抛出异常的先前位置开始的堆栈跟踪结束--- at   System.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()   ---从抛出异常的先前位置开始的堆栈跟踪结束--- at   Amazon.Runtime.Internal.RetryHandler.d__10`1.MoveNext()

2 个答案:

答案 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的行并进行更正。