2017-06-16 187 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的行並對其進行更正。