【发布时间】:2018-11-10 01:14:52
【问题描述】:
我正在将网站从标准 ASP.NET 网站转换为使用 Azure。该网站之前已获取管理员用户上传的 Excel 文件并将其保存在文件系统中。作为迁移的一部分,我将此文件保存到 Azure 存储。通过 Azure SDK 对我的本地存储运行时,它运行良好。 (我正在使用 1.3 版本,因为我不想在开发过程中升级。)
但是,当我将代码指向 Azure 存储本身时,该过程通常会失败。我得到的错误是: 发生 System.IO.IOException
Message=Unable to read data from the transport connection: The connection was closed.
Source=Microsoft.WindowsAzure.StorageClient
StackTrace:
at Microsoft.WindowsAzure.StorageClient.Tasks.Task`1.get_Result()
at Microsoft.WindowsAzure.StorageClient.Tasks.Task`1.ExecuteAndWait()
at Microsoft.WindowsAzure.StorageClient.CloudBlob.UploadFromStream(Stream source, BlobRequestOptions options)
at Framework.Common.AzureBlobInteraction.UploadToBlob(Stream stream, String BlobContainerName, String fileName, String contentType) in C:\Development\RateSolution2010\Framework.Common\AzureBlobInteraction.cs:line 95
InnerException:
代码如下:
public void UploadToBlob(Stream stream, string BlobContainerName, string fileName,
string contentType)
{
// Setup the connection to Windows Azure Storage
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(GetConnStr());
DiagnosticMonitorConfiguration dmc = DiagnosticMonitor.GetDefaultInitialConfiguration();
dmc.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
dmc.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;
DiagnosticMonitor.Start(storageAccount, dmc);
CloudBlobClient BlobClient = null;
CloudBlobContainer BlobContainer = null;
BlobClient = storageAccount.CreateCloudBlobClient();
// For large file copies you need to set up a custom timeout period
// and using parallel settings appears to spread the copy across multiple threads
// if you have big bandwidth you can increase the thread number below
// because Azure accepts blobs broken into blocks in any order of arrival.
BlobClient.Timeout = new System.TimeSpan(1, 0, 0);
Role serviceRole = RoleEnvironment.Roles.Where(s => s.Value.Name == "OnlineRates.Web").First().Value;
BlobClient.ParallelOperationThreadCount = serviceRole.Instances.Count;
// Get and create the container
BlobContainer = BlobClient.GetContainerReference(BlobContainerName);
BlobContainer.CreateIfNotExist();
//delete prior version if one exists
BlobRequestOptions options = new BlobRequestOptions();
options.DeleteSnapshotsOption = DeleteSnapshotsOption.None;
CloudBlob blobToDelete = BlobContainer.GetBlobReference(fileName);
Trace.WriteLine("Blob " + fileName + " deleted to be replaced by newer version.");
blobToDelete.DeleteIfExists(options);
//set stream to starting position
stream.Position = 0;
long totalBytes = 0;
//Open the stream and read it back.
using (stream)
{
// Create the Blob and upload the file
CloudBlockBlob blob = BlobContainer.GetBlockBlobReference(fileName);
try
{
BlobClient.ResponseReceived += new EventHandler<ResponseReceivedEventArgs>((obj, responseReceivedEventArgs)
=>
{
if (responseReceivedEventArgs.RequestUri.ToString().Contains("comp=block&blockid"))
{
totalBytes += Int64.Parse(responseReceivedEventArgs.RequestHeaders["Content-Length"]);
}
});
blob.UploadFromStream(stream);
// Set the metadata into the blob
blob.Metadata["FileName"] = fileName;
blob.SetMetadata();
// Set the properties
blob.Properties.ContentType = contentType;
blob.SetProperties();
}
catch (Exception exc)
{
Logging.ExceptionLogger.LogEx(exc);
}
}
}
我已尝试对代码进行多种不同的更改:在替换之前删除 blob(尽管问题也存在于新 blob 上)、设置容器权限、不设置权限等。
【问题讨论】:
-
我会对代码进行一些更改,但它们不会导致您看到的问题。你真的需要totalBytes吗?您是否尝试过没有收到响应的事件处理程序?
-
事件处理程序被抛出只是为了看看传输是否有任何事情发生。它似乎对性能没有影响。
-
另外,我应该问:这段代码在一个单独的项目中运行,该项目作为 DLL 编译到 Web 角色中。 (Web 角色只是一个 Web 解决方案项目。)这有什么不同吗?代码是否需要实际存在于角色本身中? (我对此表示怀疑,因为它偶尔会起作用,但我想我应该问一下。)
-
您能否展示一下您的 Azure Blob 连接是如何配置的?你确定在项目文件中配置好 http/https 设置了吗? GetConnStr() 返回什么? - 但请不要发布您的实际访问密钥 :)
-
另外,
BlobClient.ParallelOperationThreadCount = serviceRole.Instances.Count;是干什么用的?
标签: azure azure-storage