#azure #exception #servicebus
#azure #исключение #Служебная шина
Вопрос:
У нас есть архитектура, построенная вокруг служебной шины, которая работает хорошо. В настоящее время мы также используем служебную шину с тем же интервалом между именами для ведения журнала через специальный приемник Serilog (который будет заменен на datadog).
Это привело к тому, что в нашей тестовой среде мы иногда регулировались через служебную шину (мы используем стандарт, а не премиум). Мы знаем, что это проблема с нашей стороны, и работаем над ее решением.
Однако я хочу обновить наш код, чтобы более корректно обрабатывать исключение регулирования и, возможно, добавить задержку перед повторной попыткой.
Что не ясно из документации, так это детали исключения:
https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-throttling
В настоящее время мы перехватываем исключение MessagingException — неясно, будет ли выдано это сообщение.
Кто-нибудь обрабатывал ограниченные исключения таким образом?
На данный момент разрешение, похоже, улавливает ошибку, сверьте сообщение об исключении с сообщением об исключении (я думаю, что просмотр кода ошибки является наименее тесно связанной реализацией) и поместите в него выделенный код для реагирования на него.
Ответ №1:
У нас есть несколько исключений в служебной шине, таких как QuotaExceededExceptions, ServerBusyExceptions, MessageSizeExceededExceptions, TransactionSizeExceededExceptions.
И в некоторых условиях регулирования существует несколько попыток для обеспечения доставки сообщений в конце.
С помощью Azure Monitor мы можем обрабатывать ограничения из метрик: ниже приведены несколько шагов, которые я прошел:
- Можно проверять запросы на дросселирование
- Мы можем выбрать ServiceBusThrottling
Вы можете ознакомиться с этим блогом, чтобы узнать об обработке вызовов с помощью функций Azure для служебной шины.
Ниже приведен пример кода:
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.ServiceBus.Messaging;
using System.Data.SqlClient;
using System.Text;
using System;
namespace BallardChalmers.BackgroundFunctions
{
public static class BallardChalmersBackgroundTaskCreated
{
[FunctionName("BallardChalmersBackgroundTaskCreated")]
public static void
Run([ServiceBusTrigger("BallardChalmersBackgroundTaskCreated", AccessRights.Send, Connection = "ServiceBusConnection")]string queueMessage, TraceWriter log)
{
log.Info($"Service_TaskManager task added to queue with ID: {queueMessage}");
try
{
string connectionString = System.Configuration.ConfigurationManager.AppSettings["SQLConnectionString"]; ;
using (SqlConnection connection = new SqlConnection(connectionString))
{
// Create wait period between 1 and 60 seconds
System.Random random = new System.Random();
int waitPeriod = random.Next(1, 60);
log.Info($"Wait period: {waitPeriod.ToString()}");
connection.Open();
StringBuilder sb = new StringBuilder();
sb.Append("INSERT FunctionsLog ");
sb.Append("SELECT '" queueMessage "','Started','" DateTime.Now.ToString() "','" DateTime.Now.ToString() "'," waitPeriod.ToString());
String sql = sb.ToString();
log.Info($"Insert command: {sql}");
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.ExecuteNonQuery();
}
log.Info($"Inserted to FunctionsLog");
System.Threading.Thread.Sleep(1000 * waitPeriod);
log.Info($"Wait completed");
sb = new StringBuilder();
sb.Append("UPDATE FunctionsLog ");
sb.Append("SET [Status]='Completed', Updated='" DateTime.Now.ToString() "'");
sb.Append("WHERE ID='" queueMessage "'");
sql = sb.ToString();
log.Info($"Update command: {sql}");
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.ExecuteNonQuery();
}
log.Info($"Updated to FunctionsLog");
}
}
catch (SqlException e)
{
log.Error($"Error writing to database: {e.Message ":::" e.StackTrace}");
}
}
}
}