在使用Windows Azure Storage Service 的时候, 通常会遇到各种各样的问题。

例如网络连接不稳定,导致请求没有发出去。删除一个Blob Container 之后又立刻创建同名的Container。

这些情况都有可能使得你的代码抛出异常。这种异常我们通常叫他:Transient Fault 翻译成中文就是短暂性异常。

处理这种异常最简单有效的途径就是过几秒钟之后再重新发送请求。

Retry Policy就是用来帮助我们完成这样一项工作的。

Retry Policy中自带三个已经封装好了可以直接使用的类,分别有着不同的重试策略。

1.LinearRetry

这个类提供一个平行线式的重试策略

上图展示了LinearRetry的重试策略。它一共重试了五次,每一次的时间间隔都是5秒,第六次由于已经超过了预设定的重试次数,所以就放弃了。

使用LinearRetry的方法如下。

static string accountName = "<storage account name>";
static string accountKey = "<storage account key>";
static void Main(string[] args)
{
var storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
string blobContainerName = "temp-" + DateTime.UtcNow.Ticks;
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
IRetryPolicy exponentialRetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(), );
blobClient.RetryPolicy = exponentialRetryPolicy;
CloudBlobContainer blobContainer = blobClient.GetContainerReference(blobContainerName);
blobContainer.Create();
Console.WriteLine("Blob container created.");
Console.ReadLine();
}

2.ExponentialRetry

这个类提供了一个递增式的重试策略

很明显这是一个指数级别的重试策略,每一次重试的时间间隔都是之前的2倍。

使用ExponentialRetry方法如下:

static string accountName = "<storage account name>";
static string accountKey = "<storage account key>";
static void Main(string[] args)
{
var storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
string blobContainerName = "temp-" + DateTime.UtcNow.Ticks;
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(), );
blobClient.RetryPolicy = linearRetryPolicy;
CloudBlobContainer blobContainer = blobClient.GetContainerReference(blobContainerName);
IRetryPolicy noRetryPolicy = new NoRetry();
BlobRequestOptions requestOptions = new BlobRequestOptions()
{
RetryPolicy = noRetryPolicy,
};
blobContainer.Create(requestOptions);
Console.WriteLine("Blob container created.");
Console.ReadLine();
}

3.NoRetry

这个类的重试策略就是不重试,这个策略看似矛盾,其实它是用来配合之前两种策略来使用的,当你希望一个Blob Container的所有操作都能应用重试策略,唯独Create Blob不使用重试策略的时候你就需要用到NoRetry了。 代码如下:

static string accountName = "<storage account name>";
static string accountKey = "<storage account key>";
static void Main(string[] args)
{
var storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
string blobContainerName = "temp-" + DateTime.UtcNow.Ticks;
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(), );
blobClient.RetryPolicy = linearRetryPolicy;
CloudBlobContainer blobContainer = blobClient.GetContainerReference(blobContainerName);
IRetryPolicy noRetryPolicy = new NoRetry();
BlobRequestOptions requestOptions = new BlobRequestOptions()
{
RetryPolicy = noRetryPolicy,
};
blobContainer.Create(requestOptions);
Console.WriteLine("Blob container created.");
Console.ReadLine();
}

除了以上三个已经封装好的类以外,我们还可以自己创建自定义的重试策略类, 我们只需要实现IRetryPolicy接口即可。

实现自定义类的一个好处是可以自定义控制在何种特定情况下才进行重试。

下面代码将自定义一个实现了IRetryPolicy接口的 自定义类。

public class ContainerBeingDeletedRetryPolicy : IRetryPolicy
{
int maxRetryAttemps = 10; TimeSpan defaultRetryInterval = TimeSpan.FromSeconds(5); public ContainerBeingDeletedRetryPolicy(TimeSpan deltaBackoff, int retryAttempts)
{
maxRetryAttemps = retryAttempts;
defaultRetryInterval = deltaBackoff;
} public IRetryPolicy CreateInstance()
{
return new ContainerBeingDeletedRetryPolicy(TimeSpan.FromSeconds(2), 5);
} public bool ShouldRetry(int currentRetryCount, int statusCode, Exception lastException, out TimeSpan retryInterval, OperationContext operationContext)
{
retryInterval = defaultRetryInterval;
if (currentRetryCount >= maxRetryAttemps)
{
return false;
}
//Since we're only interested in 409 status code, let's not retry any other operation.
if ((HttpStatusCode)statusCode != HttpStatusCode.Conflict)
{
return false;
}
//We're only interested in storage exceptions so if there's any other exception, let's not retry it.
if (lastException.GetType() != typeof(StorageException))
{
return false;
}
else
{
var storageException = (StorageException)lastException;
string errorCode = storageException.RequestInformation.ExtendedErrorInformation.ErrorCode;
if (errorCode.Equals("ContainerBeingDeleted"))
{
return true;
}
else
{
return false;
}
}
return true;
}
}

 使用代码如下:

static string accountName = "<storage account name>";
static string accountKey = "<storage account key>";
static void Main(string[] args)
{
var storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
string blobContainerName = "temp-" + DateTime.UtcNow.Ticks;
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
IRetryPolicy linearRetryPolicy = new LinearRetry(TimeSpan.FromSeconds(), );
blobClient.RetryPolicy = linearRetryPolicy;
CloudBlobContainer blobContainer = blobClient.GetContainerReference(blobContainerName);
blobContainer.Create();
Console.WriteLine("Blob container created.");
blobContainer.Delete();
Console.WriteLine("Blob container deleted.");
IRetryPolicy containerBeingDeletedRetryPolicy = new ContainerBeingDeletedRetryPolicy(TimeSpan.FromSeconds(), );
BlobRequestOptions requestOptions = new BlobRequestOptions()
{
RetryPolicy = containerBeingDeletedRetryPolicy,
};
blobContainer.Create(requestOptions);
Console.WriteLine("Blob container created.");
Console.ReadLine();
}

这个类只用于处理返回409错误并且错误信息 "Blob container created." 的错误,其他错误则忽略掉了。

总结:

像上面这种,在一个方法中删除一个container并且重建同名container的情况很容易就产生 Transient Fault。

这时使用RetryPolicy就能够很好的解决这种异常了!

Windows Azure Storage 之 Retry Policy (用来处理短暂性错误-Transient Fault)的更多相关文章

  1. [New Portal]Windows Azure Storage (14) 使用Azure Blob的PutBlock方法,实现文件的分块、离线上传

    <Windows Azure Platform 系列文章目录> 相关内容 Windows Azure Platform (二十二) Windows Azure Storage Servic ...

  2. [SDK2.2]Windows Azure Storage (15) 使用WCF服务,将本地图片上传至Azure Storage (上) 服务器端代码

    <Windows Azure Platform 系列文章目录> 这几天工作上的内容,把项目文件和源代码拿出来给大家分享下. 源代码下载:Part1 Part2 Part3 我们在写WEB服 ...

  3. Windows Azure Storage (18) 使用HTML5 Portal的Azure CDN服务

    <Windows Azure Platform 系列文章目录> Update:2015-04-15 如果读者使用的是国内由世纪互联运维的Azure China服务,请参考笔者的文档:Azu ...

  4. Windows Azure Storage (19) 再谈Azure Block Blob和Page Blob

    <Windows Azure Platform 系列文章目录> 请读者在参考本文之前,预习相关背景知识:Windows Azure Storage (1) Windows Azure St ...

  5. Windows Azure Storage (21) 使用AzCopy工具,加快Azure Storage传输速度

    <Windows Azure Platform 系列文章目录> Update 2016-09-28 想要在Azure云端,使用AzCopy工具,从Azure China 上海数据中心存储账 ...

  6. Windows Azure Storage (22) Azure Storage如何支持多级目录

    <Windows Azure Platform 系列文章目录> 熟悉Azure平台的读者都知道,Azure Blob有三层架构.如下图:(注意blob.core.chinacloudapi ...

  7. Windows Azure Storage图形界面管理工具

    上一篇我们介绍了用PowerShell将Windows Azure的存储服务当网盘来使用.如果感觉还不够简单,那么这次我们来看看还有哪些使用起来更方便的图形界面管理工具吧.当然,这些工具必要支持中国版 ...

  8. [转]探索 Windows Azure Storage

    本文转自:https://msdn.microsoft.com/zh-tw/jj573842 概觀 儲存服務 (Storage services) 在 Windows Azure 運算模擬器中提供了可 ...

  9. Windows Azure Storage (6) Windows Azure Storage之Table

    <Windows Azure Platform 系列文章目录> 最近想了想,还是有必要把Windows Azure Table Storage 给说清楚. 1.概念 Windows Azu ...

随机推荐

  1. Django 基本命令

    1. 新建一个 django project django-admin.py startproject project-name 一个 project 为一个项目,project-name 项目名称, ...

  2. cxf客户端动态调用空指针异常

    异常信息如下: 二月 , :: 上午 org.apache.cxf.common.jaxb.JAXBUtils logGeneratedClassNames 信息: Created classes: ...

  3. Remoting and web services using Spring[摘自官网]

    spring document url: http://docs.spring.io/spring/docs/ Using Hessian First we’ll have to create a n ...

  4. PHP AJAX JSONP实现跨域请求使用实例

    在之前我写过“php返回json数据简单实例”,“php返回json数据中文显示的问题”和“在PHP语言中使用JSON和将json还原成数组”.有兴趣的童鞋可以看看 今天我写的是PHP AJAX JS ...

  5. PostGr-SQL 基本概念

    http://wenjiesu.iteye.com/blog/801129 [什么是schema?] 究竟什么是schema?这个问题困扰了我很久. 我们只讨论数据库中的schema,而不讨论XML中 ...

  6. 微信小程序wafer

    1.Centos 重启nginx systemctl restart|stop|start|status nginx.service status是状态,可以看出nginx是否正在运行! system ...

  7. JDBC详解(转)

    原文链接:http://blog.csdn.net/cai_xingyun/article/details/41482835 什么是JDBC? Java语言访问数据库的一种规范,是一套API JDBC ...

  8. IE 6 ~ 9 CSS Hack 写法总结

    IE 6 ~ 9 CSS Hack 写法总结 24th 四, 14 lip2up [code lang="css"]_color: red;    /* ie6 */*color: ...

  9. Glide 魔法般的自定义扩展

    使用过Glide的朋友都明白,简单的用法就是: Glide.with(context) .load("http://inthecheesefactory.com/uploads/source ...

  10. AVAudioPlayer播放本地音频

    AVAudioPlayer苹果官方上说一般用于播放本地音频,不能用于播放网络上的音频. 具体的代码:先导入 #import <AVFoundation/AVFoundation.h> // ...