使用Python递归下载Azure Blob存储内容时遇重试策略不允许重试错误
解决Azure Blob递归下载时的"Retry policy did not allow for a retry"错误
嘿,我来帮你搞定这个头疼的错误!这个报错通常是重试次数耗尽、网络波动导致连接超时,或是权限、Blob路径配置出了问题,结合你用递归下载的场景,还有可能是批量请求时的重试策略扛不住不稳定的网络。下面给你几个实用的解决思路:
1. 自定义重试策略,给请求多几次机会
Azure SDK默认的重试策略可能不够用,你可以手动配置更宽松的重试规则,比如增加重试次数、拉长重试间隔,用指数退避的方式让请求有足够时间恢复:
from azure.storage.blob import BlobServiceClient, ExponentialBackoffRetry # 配置最多重试10次,初始等待1秒,之后每次间隔翻倍 retry_policy = ExponentialBackoffRetry(max_retries=10, initial_backoff=1) # 创建Blob服务客户端时带上这个重试策略 blob_service_client = BlobServiceClient.from_connection_string( conn_str="你的Azure连接字符串", retry_policy=retry_policy )
2. 检查Blob路径和容器名称有没有搞混
你的路径是/demo/test1,这里demo是容器,test1是Blob的前缀,别把容器和Blob路径搞混了!比如遍历Blob的时候,要确保容器客户端指向的是demo,并且前缀参数是test1而不是/test1:
# 假设session是指向demo容器的ContainerClient blobs = session.list_blobs(name_starts_with="test1") # 注意不要加斜杠
3. 确认权限和网络能正常访问Azure
- 先检查你的Azure凭据(连接字符串或SAS令牌)有没有
Read权限,没权限的话再重试也没用; - 测试下网络能不能连上Azure Blob的端点,比如用
curl试试公开Blob的URL(如果允许的话),排除网络不通的问题。
4. 给单个Blob下载加单独重试逻辑
递归下载的时候,单个Blob失败别直接中断整个流程,给每个Blob单独加重试,避免一错全错:
import os import time from azure.storage.blob import BlobClient def download_contents_azure(self, session, content, dir_name): """从Azure云下载指定内容 参数: session (obj) -- Azure blob会话对象 content (list) -- 需要从云端下载的子客户端内容部分 dir_name (str) -- 用于存储下载内容的文件夹名称 返回值: None """ # 先创建本地文件夹,不存在就新建 os.makedirs(dir_name, exist_ok=True) for item in content: # 拿到Blob的名称,不管传入的是字符串还是Blob对象 blob_name = item if isinstance(item, str) else item.name local_save_path = os.path.join(dir_name, blob_name) max_retries = 3 retry_count = 0 download_success = False while retry_count < max_retries and not download_success: try: # 拿到Blob客户端并下载 blob_client = session.get_blob_client(blob_name) with open(local_save_path, "wb") as local_file: local_file.write(blob_client.download_blob().readall()) download_success = True print(f"Blob {blob_name}下载成功!") except Exception as e: retry_count += 1 if retry_count == max_retries: print(f"Blob {blob_name}下载失败,已经重试了{max_retries}次:{str(e)}") raise # 如果你想终止流程就抛出,不想的话可以注释掉,跳过这个Blob print(f"Blob {blob_name}下载失败,正在重试第{retry_count}次...") time.sleep(2 ** retry_count) # 指数退避等待,避免频繁请求
5. 排查是不是Blob本身有问题
如果某个Blob不存在或者已经损坏,请求肯定会失败,而且重试也没用。你可以在下载前先验证Blob是否存在:
blob_client = session.get_blob_client(blob_name) if not blob_client.exists(): print(f"Blob {blob_name}不存在,跳过下载") continue
内容的提问来源于stack exchange,提问作者Sruthi
相关产品推荐
相关产品推荐

