AuthenticationFailed хранилище таблиц Azure

Мы получаем случайную ошибку из хранилища таблиц при доступе к данным:

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.

В чем причина этой ошибки? Мы читали, что может возникнуть проблема с отметкой времени, если время сервера отключено, но почему время на нашем живом сервере будет неправильным и почему тогда ошибка не возникает постоянно?


person Helo    schedule 19.06.2012    source источник


Ответы (2)


Хорошо, я наконец выяснил, в чем проблема. У меня было плохое сочетание статических и нестатических внутренних переменных в моем классе 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, заключался в том, что мы использовали неправильные учетные данные для учетной записи хранения, что мы не могли увидеть в полученной трассировке стека. Не знаю, где парень из Microsoft нашел информацию, но я рад, что связался с ними.

person Helo    schedule 08.08.2012

Отключение времени на сервере - частая причина проблем такого типа, но поскольку ваше приложение работает в Azure и этого не происходит, я бы исключил это.

Как вы указываете в вопросе, у вас на сайте в любой момент времени находится от 200 до 500 пользователей. Это означает, что у вас будут тысячи транзакций, которые работают правильно, и только очень небольшое количество ошибок. У меня есть 2 предложения:

  1. Позвоните в Microsoft и сообщите свой RequestId и время, чтобы они могли расследовать настоящую причину.
  2. Реализуйте политику повтора. Как вы, возможно, знаете, Table Storage уже поставляется с политика повтора. Но в вашем случае этого будет недостаточно, потому что эта политика повтора не повторяет попытку с кодами ошибок 403 (и всех остальных 400). Вот почему вы можете подумать о создании настраиваемая политика повтора. Люди могут не согласиться, но я бы рассматривал этот тип проблемы как временную ошибку, поскольку она случается случайным образом, вероятно, на <0,5% всех ваших транзакций. И в этом случае я бы справился с этим, используя политику повтора.
person Sandrino Di Mattia    schedule 19.06.2012
comment
Спасибо за ответ, я сам рассматривал возможность индивидуальной повторной попытки, но, вероятно, сначала стоит попробовать связаться с Microsoft. - person Helo; 21.06.2012
comment
Было бы интересно, если бы вы могли опубликовать их ответ в этом вопросе. - person Sandrino Di Mattia; 21.06.2012
comment
Конечно, я опубликую решение, если найду его. Пока мы говорим, я переписываюсь с инженером Microsoft. - person Helo; 21.06.2012
comment
@ Здравствуйте, вы получили ответ? - person Blowsie; 03.10.2012