MassTransit (поверх RabbitMQ) IServiceBus.Publish () неожиданно зависает

Я разрабатываю веб-решение с использованием MassTransit + RabbitMQ. Некоторое время назад я заметил, что когда я запускаю свои интеграционные тесты, некоторые из них начинают неожиданно и очень непоследовательно зависать в течение очень долгого времени. После непродолжительного расследования я обнаружил, что мой код висит где-то внутри метода ServiceBus.Publish (T message).

К сожалению, документация MassTransit и сообщения в блогах, которые я нашел, не дают ответа на вопрос, в чем причина и как решить эту проблему. Надеюсь, здесь кто-то может помочь решить эту проблему.

Вот как я инициализирую служебную шину:

ServiceBusFactory.New(sbc =>
      {
        sbc.ReceiveFrom(busAddress);
        sbc.UseRabbitMq(r =>
        {
          r.ConfigureHost(new Uri(busAddress),
            cfg =>
            {
              if (!string.IsNullOrEmpty(busUser) && !string.IsNullOrEmpty(busPass))
              {
                cfg.SetPassword(busPass);
                cfg.SetUsername(busUser);
              }
            });
        });

        sbc.UseControlBus();
        sbc.SetCreateMissingQueues(true);
        sbc.SetCreateTransactionalQueues(true);
        sbc.SetNetwork("workgroup");
        sbc.UseBsonSerializer();
        sbc.SetDefaultRetryLimit(2);
        sbc.SetDefaultTransactionTimeout(new TimeSpan(0, 0, timeoutSec));

        sbc.Validate();
      });

Значение timeoutSec - 10 Служебная шина инициализируется один раз и регистрируется в контейнере Autofac.

Публикация происходит путем вызова метода IServiceBus.Publish (...).

Одно из решений - обернуть метод Publish (...) в Task и использовать метод Task.Wait (...) для обеспечения тайм-аута, но это не похоже на хорошее решение.

Буду очень признателен за любую помощь!

ВАЖНОЕ ОБНОВЛЕНИЕ 26 января 2017 г .: этот вопрос относится к MT v2. Похоже, что у MT v3 аналогичная проблема, если забыть "ждать". Моя проблема не связана с "ожиданием" и в настоящее время (до сих пор) не имеет хорошего решения (насколько мне известно). Я настоятельно рекомендую всем перейти на MT v3.


person Volodymyr Usarskyy    schedule 25.04.2015    source источник


Ответы (2)


Send и Publish в MassTransit v3 по своей природе асинхронны. Вот как они устроены. Вы получаете типичную проблему при вызове асинхронных методов, не ожидая их - вызывающий контекст удаляется до завершения задачи. Это очень часто. Вы должны дождаться этого. MassTransit предоставляет утилиту для вызова его из синхронного метода:

TaskUtil.Await(() => bus.Publish(message));
person Alexey Zimarev    schedule 24.01.2017
comment
Для тех, кто недавно присоединился к сообществу MT, может быть очевидно, что отправка и публикация в MassTransit асинхронны по своей природе, но это не так. Они стали асинхронными только начиная с v3. Если вы внимательно прочитаете мой вопрос, то увидите, что он был опубликован намного раньше, чем был выпущен MT v3 (5 месяцев, если быть точным), и даже раньше, чем был впервые представлен TaskUtil. Также, если вы прочитаете тему в группах Google, вы увидите, что моя проблема не такая уж типичная. Пожалуйста, исправьте свой ответ, чтобы не запутать людей, которые все еще используют MT v2 и могут найти этот ответ - person Volodymyr Usarskyy; 25.01.2017
comment
Здесь не нужно защищаться. Речь идет не о MassTransit, а об async / await в целом, многие были здесь и столкнулись с той же проблемой. Если вы читаете мой ответ, это не было сделано для того, чтобы покровительствовать вам, и я понимаю, что вы уже давно решили свои проблемы, но нам нужно помочь людям, которые прочитают этот вопрос (и ответ) сегодня и завтра. Я обновил свой ответ, явно упомянув v3, спасибо, что указали на это. - person Alexey Zimarev; 25.01.2017
comment
Я указываю, что ваш ответ не отвечает на исходный вопрос, и объясняю, почему это не так. Как я уже сказал, без этого крошечного замечания о v3 люди, которые вынуждены использовать v2, будут полностью сбиты с толку и будут копаться в совершенно другом направлении. Спасибо за обновление! - person Volodymyr Usarskyy; 26.01.2017
comment
@AlexeyZimarev, не могли бы вы указать мне на хорошее чтение о том, что TaskUtil.Await(() => bus.Publish(message)); MassTransit является лучшей альтернативой, чем bus.Publish(message).GetAwaiter().GetResult();. Я обнаружил аналогичную проблему и, заключив ее в TaskUtil, исправил ее, но я не понимаю, почему ожидания задачи другим способом недостаточно . Та - person diegosasw; 13.05.2019

Я задал тот же вопрос группе Google MassTransit, и один из участников указал мне на свой вопрос и на единственное (на данный момент) решение: https://groups.google.com/forum/#!msg/masstransit-Discussion/oC1FOe6KsAU/VdoTrkcdHS0J

По сути, кажется, что единственный способ решить мою проблему - это обернуть код публикации сообщений в Task.

person Volodymyr Usarskyy    schedule 18.05.2015