На наших серверах запущена служба Windows, которая прослушивает шину событий, обрабатывает события, вставляя или получая записи из хранилища таблиц Azure.
Проблема в том, что в часы пик почти каждый день требуется много времени для обработки запроса к хранилищу таблиц Azure, из-за чего происходит огромный всплеск необработанных событий в шине событий.
Это ошибка времени ожидания:
{"EndOfTail":false,"UserFeeds":null,"Message":"The operation has timed out.","StackTrace":" at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext) in c:\\Program Files (x86)\\Jenkins\\workspace\\release_dotnet_master\\Lib\\ClassLibraryCommon\\Core\\Executor\\Executor.cs:line 649\r\n at Microsoft.WindowsAzure.Storage.Table.TableQuery`1.<>c__DisplayClass7.<ExecuteInternal>b__6(IContinuationToken continuationToken) in c:\\Program Files (x86)\\Jenkins\\workspace\\release_dotnet_master\\Lib\\ClassLibraryCommon\\Table\\TableQuery.cs:line 430\r\n at Microsoft.WindowsAzure.Storage.Core.Util.CommonUtility.<LazyEnumerable>d__0`1.MoveNext() in c:\\Program Files (x86)\\Jenkins\\workspace\\release_dotnet_master\\Lib\\Common\\Core\\Util\\CommonUtility.cs:line 322\r\n at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()\r\n at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)\r\n at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)\r\n at Rebtel.Service.UserFeed.DataLayer.UserFeedRepository.<Execute>d__31.MoveNext() in C:\\TeamCity\\buildAgent\\work\\18bc44b16693ee8a\\BackendServices\\Backend\\Rebtel.Service.UserFeed\\DataLayer\\UserFeedRepository.cs:line 531\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Rebtel.Service.UserFeed.DataLayer.UserFeedRepository.<GetUserFeedsByTypes>d__17.MoveNext() in C:\\TeamCity\\buildAgent\\work\\18bc44b16693ee8a\\BackendServices\\Backend\\Rebtel.Service.UserFeed\\DataLayer\\UserFeedRepository.cs:line 254\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Rebtel.Service.UserFeed.BusinessLayer.Actions.GetUserFeedAction.<Execute>d__7.MoveNext() in C:\\TeamCity\\buildAgent\\work\\18bc44b16693ee8a\\BackendServices\\Backend\\Rebtel.Service.UserFeed\\BusinessLayer\\Actions\\GetUserFeedAction.cs:line 68\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Rebtel.Service.UserFeed.UserFeedServiceImplementation.<GetActions>d__17.MoveNext() in C:\\TeamCity\\buildAgent\\work\\18bc44b16693ee8a\\BackendServices\\Backend\\Rebtel.Service.UserFeed\\UserFeedServiceImplementation.cs:line 182\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Rebtel.Platform.Service.ServiceRequestInterceptor.<TryInvokeTaskWithServiceReplyResult>d__10`1.MoveNext() in C:\\TeamCity\\buildAgent\\work\\18bc44b16693ee8a\\Platform\\Platform\\Rebtel.Platform.Backend\\Service\\ServiceRequestInterceptor.cs:line 0","Result":501}
И этот ответ занял около 603 060 миллисекунд.
Проблема не в масштабируемости учетной записи хранения Azure, потому что, если мы перезапустим службу Windows снова с более чем миллионом событий, ожидающих, они мгновенно их обработают.
Один из запросов выглядит так:
query.WherePartitionKey(QueryComparisons.Equal, userId).AndRowKey(QueryComparisons.NotEqual, LastActionRowIdTableEntity.UniqueRowKey);
Странно, когда я смотрю на графики мониторинга хранилища таблиц Azure, средняя задержка сервера не превышает 200 мс.
Ребята, вы понимаете, почему это происходит?
Редактировать. Я проверил, что мы учли все рекомендации по документации по хранению таблиц Microsoft для повышения производительности.
В точке обслуживания
- Nagle Algo выключен.
- Максимальные соединения установлены на 1000.