Несколько экземпляров служебной шины Azure для одного подписчика - PullRequest
0 голосов
/ 16 октября 2018

У меня есть ситуация, когда у меня есть основное приложение asp.net, которое регистрирует клиента подписки на тему при запуске (IHostedService), этот клиент подписки, по сути, имеет словарь обратных вызовов, которые необходимо запускать всякий раз, когда он обнаруживаетновое сообщение в теме с идентификатором (этот идентификатор хранится в свойствах сообщения).Этот словарь действует в течение всего жизненного цикла приложения и находится в памяти.

Все отлично работает на одном экземпляре основной службы приложений asp.net в Azure, как только я масштабируюсь до 2, я замечаючто иногда обратные вызовы в подписке не запускаются.Это имеет смысл, поскольку у нас теперь есть два экземпляра, каждый со своим собственным хранилищем обратных вызовов в словаре.

Поэтому я обновил код, чтобы проверить, существует ли идентификатор подписки, если нет, отменить сообщение, если да,получить обратный вызов и вызвать его.

public async Task HandleMessage(Microsoft.Azure.ServiceBus.Message message, CancellationToken cancellationToken)
{
    var queueItem = this.converter.DeserializeItem(message);

    var sessionId = // get the session id from the message
    if (string.IsNullOrEmpty(sessionId))
    {
         await this.subscriptionClient.AbandonAsync(message.SystemProperties.LockToken);
         return;
    }

    if (!this.subscriptions.TryGetValue(sessionId, out var subscription))
    {
        await this.subscriptionClient.AbandonAsync(message.SystemProperties.LockToken);
        return;
    }

    await subscription.Call(queueItem);

    // subscription was found and executed. Complete message
    await this.subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
}

Однако проблема по-прежнему возникает.Мое единственное предположение состоит в том, что при вызове AbandonAsync тот же экземпляр снова получает сообщение?

Я думаю, что я действительно пытаюсь спросить, если у меня есть несколько экземпляров клиента подписки на тему, все указывающиеодному и тому же подписчику по теме, возможно ли для всех экземпляров получить копию сообщения?Или это не гарантировано.

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

Мне удалось решить проблему, используя сеансы служебной шины.То, что я пытался сделать со словарем обратных вызовов, так или иначе, по сути, является менеджером сеансов!

Сеансы служебной шины позволяют мне иметь несколько экземпляров клиента сеанса, все указывающие на одну и ту же подписку.Тем не менее, каждый экземпляр будет знать или заботиться только о сеансах, с которыми он сейчас работает.

0 голосов
/ 16 октября 2018

если у меня есть несколько экземпляров клиента подписки на тему, все указывающие на одного и того же подписчика для темы, возможно ли для всех экземпляров получить копию сообщения?Или это не гарантировано.

Нет.Если это подписка на такая же , на которую указывают все клиенты, то только одно получит это сообщение.

Вы столкнулись с проблемой масштабирования с конкурирующими потребителями.Если вы уменьшаете масштаб, вы никогда не знаете, какой экземпляр выберет сообщение.А так как ваше состояние локально (в памяти каждого экземпляра), время от времени это не будет.Дополнительным недостатком является стоимость.Выбирая сообщения в «неправильном» экземпляре и отказываясь от него, вы будете платить более высокую плату за обмен сообщениями.

Чтобы решить эту проблему, вы должны иметь общий / централизованный или изменить архитектуру вокруг этого.,

...