1

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

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)

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

  • 我们有 5 个中型网络服务器托管我们的网站
  • 在任何给定时间,我们的网站上都有 200-500 名访客。他们不断地点击。
  • 每次点击都会从表存储中加载数据,也可以保存数据。
  • 该错误每天仅发生 20-50 次。

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

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

4

2 回答 2

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 时使用一个存储帐户,而在访问 storageAccount.Credentials 时使用另一个。这导致了 AuthenticationFailed 错误。

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

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

于 2012-08-08T14:33:14.400 回答
0

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

就像您在问题中所说的那样,在任何给定时间,您的网站上都有 200 到 500 个用户。这意味着您将拥有数千个正常工作的事务,并且只有极少数的错误。我有两个建议:

  1. 致电 Microsoft并向他们提供您的 RequestId 和时间,以便他们调查真正的原因。
  2. 实施重试策略。你可能知道,Table Storage 已经自带了重试策略。但在您的情况下,这还不够,因为此重试策略不会重试403(和所有其他 400)错误代码。这就是您可以考虑构建自定义重试策略的原因。人们可能不同意,但我认为这类问题是暂时性故障,因为它可能随机发生在您所有交易的 < 0.5% 上。在那种情况下,我会使用重试策略来处理它。
于 2012-06-19T11:03:25.433 回答