AuthenticationFailed Azure表存储

时间:2012-06-19 09:36:26

标签: exception azure azure-table-storage

访问数据时,我们从表存储中收到随机错误:

System.Data.Services.Client.DataServiceClientException: <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
 <code>AuthenticationFailed</code>
 <message xml:lang="en-US">Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:67cd9503-7a10-48a9-8c97-fee3906ac8cb
Time:2012-06-19T08:20:42.0670051Z</message>
</error>
  at System.Data.Services.Client.QueryResult.Execute()
  at System.Data.Services.Client.DataServiceRequest.Execute[TElement](DataServiceContext context, QueryComponents queryComponents)

以下是有关错误和我们的网络应用程序的一些事实:

  • 我们有5个中型网络服务器托管我们的网站
  • 在任何时候,我们的网站上有200-500个客户。他们是 经常点击。
  • 每次点击都会从表存储中加载数据,也可以保存。
  • 错误每天只发生20-50次。

令我感到困惑的是,与大量的页面加载和AJAX回调相比,这种错误很少发生。

此错误的原因是什么?我们已经读过,如果服务器时间关闭可能会出现时间戳问题,但为什么我们的实时服务器上的时间会出现错误?为什么错误不会一直发生呢?

2 个答案:

答案 0 :(得分:1)

好的,我终于找到了导致我问题的原因。我的DataSource类中有一个静态和非静态内部变量的错误组合:

private static CloudStorageAccount storageAccount;
private CharacterContext _context;

由于storageAccount变量是静态的,因此在实例化DataSource对象时,并发请求会竞争将其更改为不同的存储帐户:

public CharacterDataSource()
{
      storageAccount = CloudStorageAccount.FromConfigurationSetting(ServiceConfigurationHelper.GetTableStorageConnectionStringConfigKey(GameInstanceName));
      _context = new CharacterContext(storageAccount.TableEndpoint.AbsoluteUri, storageAccount.Credentials);
}

由于这个小问题,_context对象的实例化实际上可能在访问storageAccount.TableEndpoint.AbsoluteUri时使用一个storeage帐户,而在访问storageAccount.Credentials时则使用另一个。这导致了AuthenticationFailed错误。

storageAccount变量绝对没有理由是静态的,因此解决方案只是删除此修饰符,从那时起我们就没有更多错误了。

我从微软获得的提示是我们使用了错误的凭据来存储帐户,这是我们无法在堆栈跟踪中看到的。不知道微软的人在哪里找到了这些信息,但我很高兴我联系了他们。

答案 1 :(得分:0)

关闭服务器时间是导致此类问题的一个常见原因,但由于您的应用程序在Azure中运行并且发生的情况不是很多,我会将其排除在外。

就像您在问题中所述,您在任何特定时间都有200到500个用户。这意味着您将拥有数千个正常运行的事务,并且只有极少数的错误。我有2条建议:

  1. Call Microsoft并向他们提供您的RequestId和时间,以便他们调查真正的原因。
  2. 实施重试政策。您可能知道,Table Storage已经附带retry policy。但在您的情况下,这将是不够的,因为此重试策略doesn't retry在403(和所有其他400)错误代码上。这就是为什么你可以看看构建custom retry policy的原因。人们可能不同意,但我认为这种类型的问题是一种短暂的错误,因为它可能随机发生在&lt;所有交易的0.5%。在这种情况下,我会通过使用重试策略来处理它。