从 `azure-storage-blob-go` 迁移到新版 `azblob` SDK:以 Grafana Tempo 的 Azure 后端为实战案例
发布时间:2026/9/18 19:58:32 作者:尧图编辑部 阅读量:1,286

从azure-storage-blob-go迁移到新版azblobSDK以 Grafana Tempo 的 Azure 后端为实战案例【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempoGrafana Tempo 是一款高吞吐、低依赖的分布式链路追踪后端可将链路数据持久化到 Azure Blob Storage。本文以仓库内随附的 Azure SDK for Go 迁移指南vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/migrationguide.md为主体系统讲解如何从旧版azure-storage-blob-go模块以及azblob早期测试版迁移到新版azblob模块并穿插 Tempo 在tempodb/backend/azure下的真实用法作为佐证。读完本文你将掌握新版 SDK 的客户端构造、认证方式、分页列举与 HTTP Pipeline 配置的完整迁移路径并能在自己的 Go 项目中直接套用。为什么需要迁移简化后的 API 表面旧版azure-storage-blob-go的公开 API 是扁平的——所有客户端和支持类型都集中在azblob一个包内导致包面难以导航用户在数千个导出符号中寻找自己需要的 API 十分费力。新版azblob模块github.com/Azure/azure-sdk-for-go/sdk/storage/azblob对设计做了重构将客户端按职责拆分到多个子包中。从当前仓库的 vendor 目录vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/可以看到这套拆分后的包结构blob所有 Blob 类型共有的 API删除/恢复删除、设置元数据等container容器特有 API设置访问策略、属性等serviceBlob 服务级 API操作容器、获取账户信息等appendblob/blockblob/pageblob针对三种特定 Blob 类型的专用客户端sas共享访问签名SAS令牌的创建与操作工具bloberror存储错误码与错误处理辅助工具。Tempo 的 Azure 后端正是按这套子包来组织代码的。在 tempodb/backend/azure/azure.go 的 import 块中可以看到它同时引用了azblob、azblob/blob、azblob/bloberror、azblob/blockblob、azblob/container等多个子包——这正是新版 API 拆分后的典型用法。客户端构造从url.URL Pipeline到string URL Credential旧版方式在azure-storage-blob-go中客户端构造函数总是要求传入一个url.URL和一个Pipeline// 旧代码azure-storage-blob-go u, _ : url.Parse(https://myaccount.blob.core.windows.net/) pipeline : azblob.NewPipeline(cred, azblob.PipelineOptions{}) client : azblob.NewServiceURL(*u, pipeline) // 以 url.URL 和 Pipeline 构造新版方式在新版azblob中客户端构造函数改为接收string类型的 URL、指定的凭证类型以及可选的*ClientOptions传nil表示接受默认选项// 新代码 client, err : azblob.NewClient(my storage account URL, cred, nil)以 Tempo 的实际代码为例在 tempodb/backend/azure/azure_helpers.go 中客户端正是通过azblob.NewClient(u.String(), credential, opts)或azblob.NewClientWithSharedKeyCredential(u.String(), credential, opts)构造的其中u由url.Parse生成后再取其字符串形式传入凭证对象则直接作为第二个参数。从 vendor 目录中azblob/client.go的源码vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/client.go#L33-L85可以看到新版模块实际上提供了四个构造函数覆盖全部认证场景构造函数适用场景NewClient(serviceURL string, cred azcore.TokenCredential, options *ClientOptions)Azure AD 令牌凭证通常来自 azidentity 模块NewClientWithNoCredential(serviceURL string, options *ClientOptions)匿名访问或带 SAS 令牌的 URLNewClientWithSharedKeyCredential(serviceURL string, cred *SharedKeyCredential, options *ClientOptions)共享密钥认证NewClientFromConnectionString(connectionString string, options *ClientOptions)连接字符串认证方式的迁移Azure AD / OAuth 令牌认证旧版azure-storage-blob-go通过NewTokenCredential提供有限的 OAuth 令牌认证支持。新版azblob不再自带令牌凭证实现而是统一改用 azidentity 模块提供的 Azure Identity 凭证。这也是 Azure SDK for Go 所有服务模块的通用做法。典型用法// 新代码。cred 是由 azidentity 模块创建的 AAD 令牌凭证 cred, err : azidentity.NewDefaultAzureCredential(nil) if err ! nil { // 处理错误 } client, err : azblob.NewClient(my storage account URL, cred, nil)Tempo 对 azidentity 的运用可以印证这一点。在 tempodb/backend/azure/azure_helpers.go 中当配置use_federated_token时使用azidentity.NewWorkloadIdentityCredential(...)创建 Azure Workload Identity联邦令牌凭证当配置use_managed_identity时使用azidentity.NewManagedIdentityCredential(...)创建托管身份凭证并可通过azidentity.ClientID(cfg.UserAssignedID)指定用户分配身份的 Client ID未指定时默认使用系统分配身份。共享密钥认证通过NewSharedKeyCredential进行共享密钥认证的方式在新版中保持不变cred, err : azblob.NewSharedKeyCredential(accountName, accountKey) client, err : azblob.NewClientWithSharedKeyCredential(u.String(), cred, opts)Tempo 的默认路径正是如此。在 tempodb/backend/azure/azure_helpers.go 中注释明确写道如果未显式指定任何认证机制则默认假定使用共享密钥凭证If no authentication mechanism has been explicitly specified, assume shared key credential随后用azblob.NewSharedKeyCredential加上azblob.NewClientWithSharedKeyCredential完成构造。账户名与密钥还可以分别从环境变量AZURE_STORAGE_ACCOUNT与AZURE_STORAGE_KEY读取见 azure_helpers.go 的getStorageAccountName与getStorageAccountKey。匿名 / SAS 认证旧版通过NewAnonymousCredential构造 Pipeline 来支持匿名或 SAS 认证。新版改用专用构造函数NewClientWithNoCredential()// 新代码 client, err : azblob.NewClientWithNoCredential(public blob or blob with SAS URL, nil)从client.go的注释可以看出该构造函数专门用于匿名访问存储账户或在服务 URL 中直接携带 SAS 令牌进行访问vendor/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/client.go#L44-L57。列举 Blob / 容器从显式Marker到*runtime.Pager[T]旧版azure-storage-blob-go要求开发者显式创建Marker类型来对分页结果进行翻页每次手动将返回的Marker回传以获取下一页。新版azblob中所有返回分页值的操作统一返回*runtime.Pager[T]。Pager 是azcore运行时提供的泛型分页器自带More()与NextPage()两个方法遍历逻辑因此变得简洁一致// 新代码 pager : client.NewListBlobsFlatPager(my-container, nil) for pager.More() { page, err : pager.NextPage(context.TODO()) if err ! nil { // 处理错误 } // 处理本页结果 for _, blob : range page.Segment.BlobItems { fmt.Println(*blob.Name) } }Tempo 的 Azure 后端大量使用了 Pager 模式可以作为最佳实践参考tempodb/backend/azure/azure.go 的List方法使用container.NewListBlobsHierarchyPager(dir, ...)层级列举遍历租户/目录下的 blob 前缀BlobPrefixes用于发现后端对象tempodb/backend/azure/azure.go 的ListBlocks方法使用NewListBlobsFlatPager扁平列举配合Prefix过滤遍历某租户下的meta.json/meta.compacted.json文件来收集 block ID 列表tempodb/backend/azure/azure.go 的Find方法同样用NewListBlobsFlatPager迭代全部 blob并通过b.Properties.LastModified向回调传递对象修改时间。三处都遵循同一范式for pager.More() { page, err : pager.NextPage(ctx) ... }可见 Pager 已成为新版 SDK 分页操作的统一抽象。配置 HTTP Pipeline从显式 Pipeline 到azcore.ClientOptions旧版需要先显式构建带配置的 HTTP Pipeline再把它作为参数传给客户端构造函数。新版azblob中HTTP Pipeline 在客户端构造期间自动创建其配置通过azcore.ClientOptions类型注入// 新代码 client, err : azblob.NewClient(account, cred, azblob.ClientOptions{ ClientOptions: azcore.ClientOptions{ // 在这里配置 HTTP Pipeline 选项 Transport: ..., Retry: ..., Telemetry: ..., }, })Tempo 在这一环节做了相当细致的配置是理解azcore.ClientOptions各字段的绝佳样例见 tempodb/backend/azure/azure_helpers.goRetry设置policy.RetryOptions{MaxRetries: 1, TryTimeout: 1 * time.Minute, RetryDelay: 4 * time.Second, MaxRetryDelay: 120 * time.Second}这些重试参数从旧 SDKazure-storage-blob-go继承而来源码注释给出了旧实现出处如果上下文携带 deadline还会把TryTimeout调整为距离截止时间的剩余时长Transport克隆http.DefaultTransport并把MaxIdleConnsPerHost提升到 100减少连接周转外层再包一层instrumentation.NewTransport用于指标采集可选地Tempo 还会用hedgedhttp包一层带统计的 RoundTripper 实现对冲请求hedged requests以降低长尾延迟——对应配置项HedgeRequestsAt/HedgeRequestsUpToTelemetry设置ApplicationID: Tempo让 Azure 侧能够识别请求来源。在 Tempo 中配置新版 azblob 后端迁移指南之外Tempo 对 Azure 后端的完整配置也值得一并掌握详见 docs/sources/tempo/configuration/hosted-storage/azure.md 与 tempodb/backend/azure/config.go。Tempo 支持三种认证方式共享密钥storage_account_key、托管身份use_managed_identity/user_assigned_id与 Azure Workload Identity 联邦令牌use_federated_token。单机monolithic模式下最小配置如下storage: trace: backend: azure azure: container_name: container-name storage_account_name: storage-account-name storage_account_key: ${STORAGE_ACCOUNT_ACCESS_KEY}使用联邦令牌Workload Identity时storage: trace: backend: azure azure: container_name: container-name storage_account_name: storage-account-name use_federated_token: true配置项与默认值config.go中的RegisterFlagsAndApplyDefaults配置项默认值说明storage_account_name空可回退到环境变量AZURE_STORAGE_ACCOUNT存储账户名storage_account_key空可回退到环境变量AZURE_STORAGE_KEY共享密钥use_managed_identityfalse使用 Azure 托管身份认证use_federated_tokenfalse使用 Azure Workload Identity 联邦令牌user_assigned_id空用户分配身份的 Client IDcontainer_name空存储 block 的容器名prefix空容器内存储对象的可选前缀endpoint_suffixblob.core.windows.net目标端点用于公有云以外的区域/主权云max_buffers4同时上传的缓冲区数量buffer_size3 * 1024 * 10243 MiB代码内置默认上传块大小hedge_requests_at00 表示禁用对冲请求触发延迟hedge_requests_up_to2对冲请求最大并发数需要特别说明的是 Azurite 本地模拟Tempo 会将任何不以blob.开头的endpoint_suffix判定为 Azurite并自动切换到模拟器 URL 风格http://endpoint/accountName见 azure_helpers.go 的注释与实现。这意味着一份配置即可在本地开发与云端生产之间切换。迁移检查清单替换模块依赖将go.mod中的github.com/Azure/azure-storage-blob-go/azblob替换为github.com/Azure/azure-sdk-for-go/sdk/storage/azblob如需 Azure AD 认证再添加github.com/Azure/azure-sdk-for-go/sdk/azidentity。重写客户端构造把手动构造 Pipeline url.URL传入构造函数改为直接传stringURL 凭证 *ClientOptions可传nil。替换凭证创建用 azidentity 的NewDefaultAzureCredential/NewManagedIdentityCredential/NewWorkloadIdentityCredential替代旧版NewTokenCredential共享密钥的NewSharedKeyCredential保持不变匿名/SAS 场景改用NewClientWithNoCredential。改写分页逻辑删除显式Marker管理改用*runtime.Pager[T]的More()/NextPage()循环。迁移 Pipeline 配置把旧 Pipeline 中的重试、传输、日志等配置平移到azcore.ClientOptionsRetry、Transport、Telemetry、Logging等字段。完成以上步骤后你的代码即可与 Tempo 一样在统一、可导航、goroutine 安全的新版azblobAPI 之上构建存储层——Tempo 的全部相关实现位于 tempodb/backend/azure/可作为迁移后的参考实现。【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考