【发布时间】:2017-08-08 18:27:15
【问题描述】:
我有一个在 Windows 环境下运行良好的应用程序。使用 C# 4.6.1 编写并使用 Azure 存储上传\下载 blob 的应用程序。
我想在 linux ubuntu 服务器 (v16) 上运行相同的应用程序。在服务器上安装单声道后,我尝试运行该应用程序。程序异常崩溃。
所以,我添加了日志,发现问题来自 Azure-Storage SDK(v7.0.0,通过 nu-get 安装)。
这是我的相关代码:
CloudBlockBlob blob = container.GetBlockBlobReference(string.Join("", blob_path));
using (MemoryStream ms = new MemoryStream())
{
blob.DownloadToStream(ms); // <--- BOOM
//...
}
这是我在使用 Mono 运行时遇到的异常:
Microsoft.WindowsAzure.Storage.StorageException: read failed
---> System.IO.IOException: read failed
---> System.InvalidOperationException: Operation is not valid due to the current state of the object.
at Mono.Net.Security.MobileAuthenticatedStream.CheckThrow (System.Boolean authSuccessCheck) [0x0001b] in <2b0d86369d72459baed0cee98a8e578a>:0
at Mono.Net.Security.MobileAuthenticatedStream.get_Context () [0x00000] in <2b0d86369d72459baed0cee98a8e578a>:0
at Mono.Net.Security.MobileAuthenticatedStream.ProcessRead (Mono.Net.Security.AsyncProtocolRequest asyncRequest, Mono.Net.Security.AsyncOperationStatus status) [0x00011] in <2b0d86369d72459baed0cee98a8e578a>:0
at Mono.Net.Security.AsyncProtocolRequest.ProcessOperation (Mono.Net.Security.AsyncOperationStatus status) [0x0006b] in <2b0d86369d72459baed0cee98a8e578a>:0
at Mono.Net.Security.AsyncProtocolRequest.ProcessOperation () [0x0000d] in <2b0d86369d72459baed0cee98a8e578a>:0
at Mono.Net.Security.AsyncProtocolRequest.StartOperation () [0x00000] in <2b0d86369d72459baed0cee98a8e578a>:0
--- End of inner exception stack trace ---
at Mono.Net.Security.MobileAuthenticatedStream.EndReadOrWrite (System.IAsyncResult asyncResult, Mono.Net.Security.AsyncProtocolRequest& nestedRequest) [0x00055] in <2b0d86369d72459baed0cee98a8e578a>:0
at Mono.Net.Security.MobileAuthenticatedStream.EndRead (System.IAsyncResult asyncResult) [0x00000] in <2b0d86369d72459baed0cee98a8e578a>:0
at System.Net.WebConnection.EndRead (System.Net.HttpWebRequest request, System.IAsyncResult result) [0x000d4] in <2b0d86369d72459baed0cee98a8e578a>:0
at System.Net.WebConnectionStream.EndRead (System.IAsyncResult r) [0x000af] in <2b0d86369d72459baed0cee98a8e578a>:0
at Microsoft.WindowsAzure.Storage.Core.ByteCountingStream.EndRead (System.IAsyncResult asyncResult) [0x00000] in <1a6da444611441028237826045bb8126>:0
at Microsoft.WindowsAzure.Storage.Core.Util.StreamExtensions.WriteToSync[T] (System.IO.Stream stream, System.IO.Stream toStream, System.Nullable`1[T] copyLength, System.Nullable`1[T] maxLength, System.Boolean calculateMd5, System.Boolean syncRead, Microsoft.WindowsAzure.Storage.Core.Executor.ExecutionState`1[T] executionState, Microsoft.WindowsAzure.Storage.Core.Util.StreamDescriptor streamCopyState) [0x002c6] in <1a6da444611441028237826045bb8126>:0
at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T] (Microsoft.WindowsAzure.Storage.Core.Executor.RESTCommand`1[T] cmd, Microsoft.WindowsAzure.Storage.RetryPolicies.IRetryPolicy policy, Microsoft.WindowsAzure.Storage.OperationContext operationContext) [0x003c7] in <1a6da444611441028237826045bb8126>:0
--- End of inner exception stack trace ---
at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T] (Microsoft.WindowsAzure.Storage.Core.Executor.RESTCommand`1[T] cmd, Microsoft.WindowsAzure.Storage.RetryPolicies.IRetryPolicy policy, Microsoft.WindowsAzure.Storage.OperationContext operationContext) [0x006b5] in <1a6da444611441028237826045bb8126>:0
at Microsoft.Wind… Read more
at Microsoft.WindowsAzure.Storage.Core.ByteCountingStream.EndRead (System.IAsyncResult asyncResult) [0x00000] in <1a6da444611441028237826045bb8126>:0
at Microsoft.WindowsAzure.Storage.Core.Util.StreamExtensions.WriteToSync[T] (System.IO.Stream stream, System.IO.Stream toStream, System.Nullable`1[T] copyLength, System.Nullable`1[T] maxLength, System.Boolean calculateMd5, System.Boolean syncRead, Microsoft.WindowsAzure.Storage.Core.Executor.ExecutionState`1[T] executionState, Microsoft.WindowsAzure.Storage.Core.Util.StreamDescriptor streamCopyState) [0x002c6] in <1a6da444611441028237826045bb8126>:0
at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T] (Microsoft.WindowsAzure.Storage.Core.Executor.RESTCommand`1[T] cmd, Microsoft.WindowsAzure.Storage.RetryPolicies.IRetryPolicy policy, Microsoft.WindowsAzure.Storage.OperationContext operationContext) [0x003c7] in <1a6da444611441028237826045bb8126>:0
--- End of inner exception stack trace ---
at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T] (Microsoft.WindowsAzure.Storage.Core.Executor.RESTCommand`1[T] cmd, Microsoft.WindowsAzure.Storage.RetryPolicies.IRetryPolicy policy, Microsoft.WindowsAzure.Storage.OperationContext operationContext) [0x006b5] in <1a6da444611441028237826045bb8126>:0
at Microsoft.WindowsAzure.Storage.Blob.CloudBlob.DownloadRangeToStream (System.IO.Stream target, System.Nullable`1[T] offset, System.Nullable`1[T] length, Microsoft.WindowsAzure.Storage.AccessCondition accessCondition, Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions options, Microsoft.WindowsAzure.Storage.OperationContext operationContext) [0x00033] in <1a6da444611441028237826045bb8126>:0
at Microsoft.WindowsAzure.Storage.Blob.CloudBlob.DownloadToStream (System.IO.Stream target, Microsoft.WindowsAzure.Storage.AccessCondition accessCondition, Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions options, Microsoft.WindowsAzure.Storage.OperationContext operationContext) [0x00000] in <1a6da444611441028237826045bb8126>:0
at ***.DownloadFile (System.Uri url, System.IO.FileInfo file) [0x000e8] in <1a85ad8f477c4d6f8a3af08c9e99e976>:0
at ***.TimedCache+<Add>d__32.MoveNext () [0x00160] in <1a85ad8f477c4d6f8a3af08c9e99e976>:0
Request Information
RequestID:2025b933-0001-0031-2325-10951e000000
RequestDate:Tue, 08 Aug 2017 09:08:58 GMT
StatusMessage:Partial Content
Linux 机器在 Google-Cloud 下运行。解决这个问题的一个方向是 Goolge-Cloud 防火墙。可能是防火墙阻止了与 Azure-Storage 的通信?
我的代码基本上是从存储中下载一个 blob 并将其保存在本地。奇怪的是,当我检查保存文件的目录时,我可以找到一些文件。什么意思,它在某些时候起作用。
如何解决问题?
更新
根据@Amor,我试图了解问题出在哪里。我们有两种选择:
- 问题出在 C# 代码或 Mono 上。
- 问题出在环境上(Linux \ google-cloud \ ...)
我在this page 上下载了名为“Storage_REST_CS.zip”的代码。根据需要更新代码(插入我的凭据)并在 Windows 环境中对其进行测试 - 运行良好。我拿了二进制文件并将它们移动到我的 Linux 机器上进行测试。我得到了错误:
System.Net.WebException: The remote server returned an error: (403) Server failed to authenticate the request. Make sure the value of Authorization headers formed correctly including the signature.
at StorageSampleREST.RESTHelper.Retry[T] (StorageSampleREST.RESTHelper+RetryDelegate`1[T] del, System.Int32 numberOfRetries, System.Int32 msPause) [0x0001d] in <033ea4d1a16740f3b711001b7c2f09f5>:0
at StorageSampleREST.RESTHelper.Retry[T] (StorageSampleREST.RESTHelper+RetryDelegate`1[T] del) [0x00001] in <033ea4d1a16740f3b711001b7c2f09f5>:0
at StorageSampleREST.BlobHelper.ListContainers () [0x00001] in <033ea4d1a16740f3b711001b7c2f09f5>:0
at StorageSampleREST.Program.TestBlobStorage () [0x00023] in <033ea4d1a16740f3b711001b7c2f09f5>:0
现在我试图了解问题出在哪里 - 在我的代码 (c#) 或环境(Linux - Google 云)中。所以我提取了执行的 HTTP 请求(在 Mono 上失败)并尝试直接使用 cURL 运行它:
curl -i -H "x-ms-date: Wed, 09 Aug 2017 09:03:46 GMT
x-ms-version: 2009-09-19
Authorization: SharedKey userfiles:***" -X GET https://***.blob.core.windows.net/?comp=list
结果是 200 OK。什么意思,这不是任何防火墙、Linux 环境或连接的问题。
现在,重点应该放在 Mono 设置上,因为使用 cURL 执行相同的 HTTP 请求已成功完成 (200)。这不取决于我的具体代码,因为上面提到的示例代码也会发生类似的行为。
谢谢。
【问题讨论】:
标签: c# linux mono google-cloud-platform azure-blob-storage