我正在使用MassTransit + RabbitMQ开发基于Web的解决方案。前段时间我注意到,当我运行我的集成测试时,其中一些开始意外和非常不一致挂起很长时间。 经过简短的调查后,我发现我的代码挂在 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(...)方法强制执行超时,但这看起来不是一个好的解决方案。
我会非常感谢任何帮助!
重要更新2017-01-26:此问题与 MT v2 有关。如果忘记“等待”,MT v3似乎有类似的问题。我的问题与“等待”无关,目前(仍然)没有一个好的解决方案(据我所知)。我强烈建议大家迁移到MT v3。
答案 0 :(得分:1)
Send
和Publish
本质上是异步的。这就是它们的设计方式。调用异步方法而不等待它们时会出现典型问题 - 调用上下文在任务完成之前被释放。这很常见。你必须等待它。 MassTransit为您提供了一个从同步方法调用它的实用程序:
TaskUtil.Await(() => bus.Publish(message));
答案 1 :(得分:0)
我在MassTransit Google小组上提出了同样的问题,其中一位参与者向我指出了他的问题和唯一一个(此时)解决方案:https://groups.google.com/forum/#!msg/masstransit-discuss/oC1FOe6KsAU/VdoTrkcdHS0J
基本上,似乎解决我的问题的唯一方法是将消息发布代码包装到任务中。