Azure Service Bus, определите, останавливает ли OnMessage обработку
Используя Azure ServiceBus и вызов OnMessage, я ищу способ определить, прекращает ли насос событий OnMessage чтение из очереди.
Наше соединение с OnMessage настроено следующим образом:
protected virtual void DoSubscription(string queueName, Func<QueueRequest, bool> callback)
{
var client = GetClient(queueName, PollingTimeout);
var transformCallback = new Action<BrokeredMessage>((message) =>
{
try
{
var request = message.ToQueueRequest();
if (callback(request))
{
message.Complete();
}
else
{
message.Abandon();
Log.Warn("DoSubscription: Message Failed to Process Gracefully: {0}{1}", Environment.NewLine, JsonConvert.SerializeObject(request));
}
}
catch (Exception ex)
{
Log.Error("DoSubscription: Message Failed to Process With Exception:", ex);
message.Abandon();
}
});
var options = new OnMessageOptions
{
MaxConcurrentCalls = _config.GetInt("MaxThreadsPerQueue"),
AutoComplete = false,
AutoRenewTimeout = new TimeSpan(0,0,1)
};
options.ExceptionReceived += OnMessageError;
client.OnMessage(transformCallback, options);
}
Проблема, с которой мы сталкиваемся, заключается в том, что по истечении определенного периода времени, когда в очереди нет сообщений, новые сообщения, находящиеся в очереди, не могут быть получены насосом событий OnMessage до тех пор, пока приложение не будет перезапущено.
Я понимаю, что есть способы сделать это с помощью рабочих ролей, однако для целей мониторинга и управления мы решили реализовать это в запуске приложения веб-приложения.
1 ответ
Поэтому после обращения в службу поддержки Microsoft Azure не возникает событие, которое может быть перехвачено при возникновении ошибок OnMessage или OnMessageAsync. Поскольку это не блокирующие вызовы, он запускает обработчик событий и возвращается к выполняющемуся потоку, это создает проблему, чтобы определить, выполняет ли OnMessage * свою работу.
Предложения от Microsoft были:
- Создайте свою собственную реализацию класса QueueClientBase, который предоставляет методы OnClose, On *, которые вы можете обрабатывать. Однако при этом вы должны сами обрабатывать конверт сообщения.
- Используйте OnReceive в отдельном цикле потока, который вы можете перехватывать ошибки самостоятельно и немедленно повторять попытку.
Тем не менее, я исследовал некоторые средства защиты от OnMessage и обнаружил несколько вещей, которые ослабили мои страхи.
- OnMessage невероятно отказоустойчив
- Я подключил Ethernet-кабель к ноутбуку с отключенным беспроводным соединением, это разорвало соединение OnMessage с очередью служебной шины. После 10 минут ожидания я снова подключил кабель Ethernet, и OnMessage немедленно начал обрабатывать элементы в очереди.
- На Сообщение на удивление довольно стабильно. Он был запущен внутри запуска приложения global.asax.cs, сокращенно, для дней подряд с Factory IdleTimeout, установленным в 24 часа, без перезапуска веб-приложения в течение 72 часов.
В общем, сейчас я собираюсь продолжить использовать OnMessage/OnMessageAsync и следить за этим. Я буду обновлять это, если я вижу проблемы, которые меняют мое мнение об OnMessage.
В стороне - убедитесь, что вы используете OnMessage для постоянного прослушивания на веб-сайте Azure, для которого для параметра конфигурации "Всегда включено" установлено значение "Вкл.". В противном случае, если веб-запрос не поступит в OnMessage, он будет удален и сообщения больше не будут обрабатываться до тех пор, пока веб-приложение не будет повторно вызвано HTTP-запросом.