Настроить Webjob ServiceBusTriggers или имена очередей во время выполнения (без жестко заданных атрибутов)?

Есть ли способ настроить триггеры без атрибутов? Я не могу знать имена очередей заранее.

Позвольте мне объяснить мой сценарий здесь. У меня есть одна очередь служебной шины, и по разным причинам (сложная бизнес-логика подавления дубликатов) сообщения очереди должны обрабатываться по одному, поэтому у меня ServiceBusConfiguration.OnMessageOptions.MaxConcurrentCalls установлено значение 1. Таким образом, обработка сообщение удерживает всю очередь, пока не будет завершено. Излишне говорить, что это неоптимально.

Эта политика «по одному» не так проста. Сообщения могут обрабатываться параллельно, их просто нужно разделить на группы (на основе поля в сообщении), скажем, A и B. Группа A может обрабатывать свои сообщения по одному, а группа B может обрабатывать свои по одному и т.д. A и B обрабатываются параллельно, все хорошо.

Таким образом, я могу создать очередь для каждой группы, A, B, C, ... и т. д. Всего около 50 групп, поэтому 50 очередей.

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

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

(Чтобы было ясно, я знаю, как использовать INameResolver для получения имени очереди, как в Как установить имя очереди Azure WebJob во время выполнения? но хотя похоже, что это не моя проблема. Я хочу настроить триггеры для нескольких очередей при запуске для одной и той же функции, чтобы получать по очереди обработку по очереди, без повторного использования атрибута триггера 50 раз. Я подумал, что я' d спросить еще раз, так как репозиторий SDK довольно активен, и прошел год..).

Или я все неправильно делаю? Быть тупым? Что-то упустил? Буду рад любым советам по этой дилемме.


person Aaron B    schedule 14.07.2016    source источник


Ответы (2)


Узел веб-заданий Azure обнаруживает и индексирует функции с атрибутом ServiceBusTrigger при запуске. Таким образом, нет возможности настроить очереди для запуска во время выполнения.

Более простое решение для вас — создать долговременное задание и реализовать его вручную:

public class Program
{
    private static void Main()
    {
        var host = new JobHost();
        host.CallAsync(typeof(Program).GetMethod("Process"));
        host.RunAndBlock();
    }

    [NoAutomaticTriggerAttribute]
    public static async Task Process(TextWriter log, CancellationToken token)
    {
        var connectionString = "myconnectionstring";
        // You can also get the queue name from app settings or azure table ??
        var queueNames = new[] {"queueA", "queueA" };
        var messagingFactory = MessagingFactory.CreateFromConnectionString(connectionString);
        foreach (var queueName in queueNames)
        {
            var receiver = messagingFactory.CreateMessageReceiver(queueName);
            receiver.OnMessage(message =>
            {
                try
                {
                    // do something
                    ....

                    // Complete the message
                    message.Complete();
                }
                catch (Exception ex)
                {
                    // Log the error
                    log.WriteLine(ex.ToString());

                    // Abandon the message so that it can be retry.
                    message.Abandon();
                }
            }, new OnMessageOptions() { MaxConcurrentCalls = 1});
        }

        // await until the job stop or restart
        await Task.Delay(Timeout.InfiniteTimeSpan, token);
    }
}

В противном случае, если вы не хотите иметь дело с несколькими очередями, вы можете посмотреть тема/подписка Azure ServiceBus и создайте SqlFilter, чтобы отправить сообщение в нужную подписку.

Другим вариантом может быть создание собственного триггера: SDK azure webjob предоставляет точки расширения для создания собственной привязки триггера:

Удачи !

person Thomas    schedule 15.07.2016

Насколько я понимаю, ваши потребности, похоже, создают параллельную систему пакетных сообщений. Решение @Thomas хорошее, но я думаю, что Azure Batch служба с хранилищем таблиц может быть лучше и может быть вместо сложного решения очереди ServiceBus + веб-заданий с триггером.

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

person Peter Pan    schedule 20.07.2016