X30*_*61X 6 azure c#-4.0 asp.net-mvc-4
我和同事都负责为Azure表存储找到连接重试逻辑.经过一番搜索,我发现这个非常酷的Enterprise Library套件包含了Microsoft.Practices.TransientFaultHandling名称空间.
下面的几个代码示例,我结束了创建一个Incremental重试策略,我们的包装与存储调用之一retryPolicy的ExecuteAction回调处理程序:
/// <inheritdoc />
public void SaveSetting(int userId, string bookId, string settingId, string itemId, JObject value)
{
// Define your retry strategy: retry 5 times, starting 1 second apart, adding 2 seconds to the interval each retry.
var retryStrategy = new Incremental(5, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));
var storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting(StorageConnectionStringName));
try
{
retryPolicy.ExecuteAction(() =>
{
var tableClient = storageAccount.CreateCloudTableClient();
var table = tableClient.GetTableReference(SettingsTableName);
table.CreateIfNotExists();
var entity = new Models.Azure.Setting
{
PartitionKey = GetPartitionKey(userId, bookId),
RowKey = GetRowKey(settingId, itemId),
UserId = userId,
BookId = bookId.ToLowerInvariant(),
SettingId = settingId.ToLowerInvariant(),
ItemId = itemId.ToLowerInvariant(),
Value = value.ToString(Formatting.None)
};
table.Execute(TableOperation.InsertOrReplace(entity));
});
}
catch (StorageException exception)
{
ExceptionHelpers.CheckForPropertyValueTooLargeMessage(exception);
throw;
}
}
}
Run Code Online (Sandbox Code Playgroud)
感觉真棒,我去展示我的同事,他沾沾自喜地注意到我们可以做同样的事情,而不必包括企业库,因为该CloudTableClient对象已经有一个重置策略的setter.他的代码最终看起来像:
/// <inheritdoc />
public void SaveSetting(int userId, string bookId, string settingId, string itemId, JObject value)
{
var storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting(StorageConnectionStringName));
var tableClient = storageAccount.CreateCloudTableClient();
// set retry for the connection
tableClient.RetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(2), 3);
var table = tableClient.GetTableReference(SettingsTableName);
table.CreateIfNotExists();
var entity = new Models.Azure.Setting
{
PartitionKey = GetPartitionKey(userId, bookId),
RowKey = GetRowKey(settingId, itemId),
UserId = userId,
BookId = bookId.ToLowerInvariant(),
SettingId = settingId.ToLowerInvariant(),
ItemId = itemId.ToLowerInvariant(),
Value = value.ToString(Formatting.None)
};
try
{
table.Execute(TableOperation.InsertOrReplace(entity));
}
catch (StorageException exception)
{
ExceptionHelpers.CheckForPropertyValueTooLargeMessage(exception);
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题 :
除了实现之外,这两种方法之间是否有任何重大差异?他们似乎都达到了同样的目标,但是有哪些情况下最好使用一个而不是另一个?
从功能上讲,两者是相同的——它们都在出现瞬时错误时重试请求。但是有一些区别:
我喜欢瞬态故障处理块的一件事是您可以拦截重试操作,而重试策略无法执行这些操作。例如,看看下面的代码:
var retryManager = EnterpriseLibraryContainer.Current.GetInstance<RetryManager>();
var retryPolicy = retryManager.GetRetryPolicy<StorageTransientErrorDetectionStrategy>(ConfigurationHelper.ReadFromServiceConfigFile(Constants.DefaultRetryStrategyForTableStorageOperationsKey));
retryPolicy.Retrying += (sender, args) =>
{
// Log details of the retry.
var message = string.Format(CultureInfo.InvariantCulture, TableOperationRetryTraceFormat, "TableStorageHelper::CreateTableIfNotExist", storageAccount.Credentials.AccountName,
tableName, args.CurrentRetryCount, args.Delay);
TraceHelper.TraceError(message, args.LastException);
};
try
{
var isTableCreated = retryPolicy.ExecuteAction(() =>
{
var table = storageAccount.CreateCloudTableClient().GetTableReference(tableName);
return table.CreateIfNotExists(requestOptions, operationContext);
});
return isTableCreated;
}
catch (Exception)
{
throw;
}
Run Code Online (Sandbox Code Playgroud)在上面的代码示例中,我可以拦截重试操作并根据需要在那里做一些事情。这对于存储客户端库是不可能的。
说了这么多,通常建议使用存储客户端库重试策略来重试存储操作,因为它是包的一个组成部分,因此会与库的最新更改保持同步。
| 归档时间: |
|
| 查看次数: |
1973 次 |
| 最近记录: |