AWS S3 AmazonServiceException:一个带有状态SecureChannelFailure的WebException。

3

提供一个服务接收请求,生成数据并将其保存在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, Func2 endFunction, Action1 endAction, Task1 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__91.MoveNext() --- 在引发异常的上一个位置结束的堆栈跟踪 --- at Amazon.Runtime.Internal.HttpHandler1.<InvokeAsync>d__91.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()
3个回答

2
这是一个比较老的问题,但我最近遇到了一个非常相似的问题,因为我无法在谷歌上找到适当的答案,所以我想贡献一下我的解决方案。
我开始实现一个旧版 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的那一行,并加以纠正。

这个五年半前的答案今天解决了我的问题。太好了!将SecurityProtocol设置为Tls12就可以解决问题,即使在更改之前该设置中有其他可用选项。(在Visual Studio调试器中显示的先前值为“Ssl3 | Tls | Tls11 | Tls12”)。显然AWS不会协商... 为了不影响应用程序的其他部分,我保存了原始值,进行了更改,调用了AWS,然后在finally块中恢复了先前的值。 - JeffK

1

S3 SDK已经实现了重试逻辑

默认情况下,上传会重试4次

创建了一个控制台应用程序来尝试复制错误。控制台应用程序尝试异步上传10-30个文件。更改AmazonS3Config中的Timeout、ReadWriteTimeout、MaxErrorRetry的值会产生异常(System.Net.WebException: The operation has timed out),但不是我们遇到的问题(Could not create SSL/TLS secure channel)。

我们假设问题可能是服务太忙而无法创建连接,这就是为什么会出现“无法创建SSL/TLS安全通道”的原因。


0

我的异常是:

A WebException with status ConnectFailure was thrown

对我来说,ServiceUrl 是 http 而不是 https,也不需要端口号。端口号被防火墙阻止了。
之前:
http://s3ws.MyDomain.com:80

之后:

https://s3ws.MyDomain.com

var s3Config = new AmazonS3Config
{
    RegionEndpoint = Amazon.RegionEndpoint.EUNorth1,
    ServiceURL = "https://s3ws.MyDomain.com",
    ForcePathStyle = true
};
return new AmazonS3Client(accessKey, secretKey, s3Config);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接