0
点赞
收藏
分享

微信扫一扫

Microsoft Azure 解决方案:如何将Blob从一个存储账户复制到另一个存储账户

51CTO 博客地址: https://blog.51cto.com/14669127

Azure培训视频地址: https://space.bilibili.com/2000820534

近期跟客户聊需求的时候遇到一个使用场景:

• Azure Resource中有一个存储账户,外部实体服务器的文件要上传到其中,需要在数据处理解决方案中读取这些文件

• 该解决方案中的Azure存储账户block了防火墙,不允许从Internet对其进行任何访问

经过讨论,最终决定:从安全角度考虑,需创建一个源blob Azure存储账户,该账户的防火墙配置为允许外部实体上传文件,然后,我们将使用此Azure功能安全地将新上载的blob复制到我们的内部仅可访问的Azure存储帐户,数据处理解决方案将在必要时访问blob文件,具体解决方案为:使用Azure函数、C#脚本和Azure.Storage.Blobs Nuget Package,编写一个执行以下操作的新函数:

• 在源Azure存储帐户中触发Function App来执行新的Blob  

• 将新blob从源Azure存储帐户复制到目标Azure存储帐户。

• 复制操作完成后,从源Azure存储帐户中删除blob。

在新的Blob上触发Function App

有几种方法可以配置Azure功能,以便在Azure存储帐户中创建新Blob时触发该功能;例如Blob Trigger, Event Grid等。本文我将选择使用一种更简单的方法,使用Function App的Blob触发器,能够监视Azure存储帐户容器中的新Blob,并在容器中创建新Blob时自动触发Function App的执行。以下是function.JSON文件中Azure函数绑定定义的JSON,该文件设置函数以在保存在源Azure存储帐户中的新Blob上触发:

{
"bindings": [
{
"name": "inputBlob",
"type": "blobTrigger",
"direction": "in",
"path": "containerName/{blobName}",
"connection": "source_storage_connectionstring"
}
]
}

说明:source_storage_connectionstring是Function App的应用程序设置,其中包含用于连接到Azure存储帐户并向其进行身份验证的Azure存储帐户连接字符串。path属性定义容器的格式和Blob的文件名

将新blob从源Azure存储帐户复制到目标Azure存储帐户

对于这种情况,我们编写一个基于C#脚本的Azure Function App,原因是为了让Function App代码更容易维护,因为它更像是存储在Git存储库中的“interpreted script”,而不是需要部署Visual Studio或.NET编译。

首先,我打开了Azure.Storage.Blobs Nuget Package,以下是Azure function的function.proj文件。

<Project Sdk="Microsoft.Net.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.Storage.Blobs" Version="12.11.0"/>
</ItemGroup>
</Project>

然后,使用Azure.Storage.Blobs命名空间编写Azure函数的run.csx C#脚本文件以包含C#代码,以执行必要的步骤,将触发Azure函数执行的blob从源Azure存储帐户复制到目标Azure存储帐户。

在C#代码的顶部,需要添加这些using语句,以包含将引用的必要命名空间

using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Azure.Storage.Sas;

传入Blob Trigger参数后,函数的Run方法的签名将如下所示:传入Blob Triger参数后,该函数的Run方式的签名将与以下所示类似:

public static async Task Run(Stream inputBlob, string blobName, ILogger log)

要将源blob复制到目标,必须在代码中完成以下步骤:

• 为将从中复制的源blob生成SAS令牌。

• 为要复制到的目标blob创建BlobClient。

• 调用BlobClient.StartCopyFromUriAsync方法以启动将源blob复制到目标blob

参照代码如下所示:

// retrieve the SOURCE and DESTINATION Storage Account Connection Strings
var sourceConnString = Environment.GetEnvironmentVariable("source_storage_connectionstring")
var destConnString = Environment.GetEnvironmentVariable("dest_storage_connectionstring")

// Create SOURCE Blob Client
var sourceBlobClient = new BlobClient(sourceConnString, "containerName", blobName);

// Generate SAS Token for reading the SOURCE Blob with a 2 hour expiration
vare sourceBlobSasToken = sourceBlobClient.GenerateSasUri(BlobSasPermissions.Read, DateTimeOffset.Now.AddHours(2));

// Create DESTINATION Blob Client
var destBlobClient = new BlobClient(destConnString, "containerName", blobName);

// Initiate Blob Copy from SOURCE to DESTINATION
await destBlobClient.StartCopyFromUriAsync(sourceBlobSasToken);

复制操作完成后,从源Azure存储帐户中删除blob。

一旦源blob被复制到目标blob,我就需要删除源blob。因此,我需要在完成复制操作检查后添加一块代码,以删除源blob。然而,我只想在复制操作成功的情况下删除源blob,以防返回的其他状态不是CopyStatus.Success或CopyStatus.Failed;例如CopyStatus。

参照代码如下所示:

// check that copy operation was successful
if (destProps.BlobCopyStatus == CopyStatus.Success) {
// Delete the SOURCE blob
sourceBlobClient.DeleteIfExists();
}

分享本文希望对大家提供帮助,谢谢阅读。

举报

相关推荐

0 条评论