Вопрос:
Я работаю над устаревшим проектом веб-API, размещенным в службах приложений Azure. Мы используем устаревший пакет NuGet WindowsAzure.ServiceBus 7.0.1 для выполнения операций в служебной шине Azure.
Предполагается, что метод PublishMessageBatch помещает сообщения в пакете в очередь. Для аутентификации я использую AzureActiveDirectoryTokenProvider.AuthenticationCallback. Однако каждый вызов PublishMessageBatch приводит к тайм-ауту, и никакие сообщения не помещаются в очередь.
Что я пробовал
Расследование тупика: Обновил свой код, добавив ConfigurationAwait(false), чтобы избежать потенциальных взаимоблокировок.
Анализ журнала: Проверив потоки журнала Службы приложений Azure, мы обнаружили, что все вызовы API приводят к коду состояния HTTP 499, что указывает на то, что клиент автоматически отменяет запрос через 2 минуты.
Для управляемого удостоверения я назначил правильные разрешения. Операции, отличные от SendBatchAsync, работают.
Я хочу понять, какие изменения мне нужно внести, чтобы PublishMessageBatch работал без истечения времени ожидания. Существуют ли какие-либо известные проблемы с WindowsAzure.ServiceBus 7.0.1 и службами приложений Azure, которые могут вызвать этот тайм-аут?
public async Task PublishMessageBatch(IEnumerable<BrokeredMessage> queueMessages)
{
await _logger.ExecuteWithInstrumentationAsync("ServiceBusQueueClient.PublishMessageBatch", string.Empty, async () =>
{
_logger.TraceInfo("Pushing message in Queue");
InitializeIfUnavailable();
await _sbQueueClient.SendBatchAsync(queueMessages).ConfigureAwait(false);
return true;
});
}
public void InitializeIfUnavailable()
{
Uri serviceBusURI = _queueConnectionString.GetServiceBusURIFromConnectionString();
string aadAuthority = _configuration.GetValue<string>(CCMConstants.AADAuthorityURL);
if (_sbQueueClient?.IsClosed != false)
{
lock (_lock)
{
if (_sbQueueClient?.IsClosed != false)
{
_logger.TraceInfo("initializing QueueClient AAD");
var azureAuthCallback = new AzureActiveDirectoryTokenProvider.AuthenticationCallback(GetTokenAsync);
_sbQueueClient = QueueClient.CreateWithAzureActiveDirectory(serviceBusURI, _queuePath, azureAuthCallback, aadAuthority, ReceiveMode.PeekLock);
_logger.TraceInfo("QueueClient initialized successfully with AAD");
_sbQueueClient.RetryPolicy = RetryPolicy.Default;
}
}
}
if (_sbNamespaceManager == null)
{
var azureAuthCallback = new AzureActiveDirectoryTokenProvider.AuthenticationCallback(GetTokenAsync);
TokenProvider token = TokenProvider.CreateAzureActiveDirectoryTokenProvider(azureAuthCallback, serviceBusURI, aadAuthority);
_sbNamespaceManager = new NamespaceManager(serviceBusURI, token);
_logger.TraceInfo("Initialized NamespaceManager for ServiceBus with AAD");
}
}
private async Task<string> GetTokenAsync(string audience, string authority, object state)
{
_logger.TraceInfo($"Value of audience: {audience}, authority: {authority} and state {state}");
return (await (new ManagedIdentityCredential("<client-id>")).GetTokenAsync(new TokenRequestContext(new[] { "https://servicebus.azure.net/.default" }), CancellationToken.None)).Token;
}
Мы помещаем все наши журналы в кластеры Kusto, и последний журнал был _logger.TraceInfo($"Value of audience: {audience}, authority: {authority} and state {state}");
, после этого в журналах не было никаких исключений или ошибок.
Я понимаю, что основная причина заключалась в отсутствии ConfigurationAwait(false) в обратном вызове GetTokenAsync. WindowsAzure.ServiceBus ожидает, что этот обратный вызов не зависит от контекста синхронизации или запроса.