我正在将MassTransit视为一个在Web项目中使用的ServiceBus实现。
我正在使用Request/Response模式,我看到接收消息和响应的消费者与处理响应的请求发布者之间存在长时间延迟;有时,似乎反应永远不会通过(让它运行10分钟,响应仍未通过)。我看到句柄委托调用响应的唯一时间是在30秒的超时时间之后,抛出超时异常;在这种情况下,处理程序委托上设置的断点被命中。
设置是一个标准事件 - 我有一个发布请求的Web应用程序,一个消耗请求和发送响应的控制台应用程序,Web应用程序处理回调中的响应。
我正在使用Castle Windsor,并使用WebActivator在Web项目中初始化容器:
[assembly: WebActivator.PreApplicationStartMethod(typeof(BootStrapper), "PreStart")]
[assembly: WebActivator.PostApplicationStartMethod(typeof(BootStrapper), "PostStart")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(BootStrapper), "Stop")]
namespace Web.App_Start
{
public static class BootStrapper
{
internal static IWindsorContainer Container { get; private set; }
public static void PreStart()
{
Container = new WindsorContainer().Install(FromAssembly.This());
}
public static void PostStart()
{
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ApiConfig.Configure(Container);
MvcConfig.Configure(Container);
}
public static void Stop()
{
if (Container != null)
Container.Dispose();
}
}
}
在Web应用程序项目(ASP.NET Web API项目)中,MassTransit的WindsorInstaller看起来像
public class MassTransitInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(AllTypes.FromThisAssembly().BasedOn<IConsumer>());
var bus = ServiceBusFactory.New(configurator =>
{
configurator.UseMsmq();
configurator.VerifyMsmqConfiguration();
configurator.UseMulticastSubscriptionClient();
configurator.ReceiveFrom("msmq://localhost/web");
configurator.EnableMessageTracing();
configurator.Subscribe(x => x.LoadFrom(container));
});
container.Register(Component.For<IServiceBus>().Instance(bus));
}
}
在控制台应用项目中,WindsorInstaller看起来像
public class MassTransitInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(AllTypes.FromAssemblyContaining<BasicRequestCommandHandler>().BasedOn<IConsumer>());
var bus = ServiceBusFactory.New(configurator =>
{
configurator.UseMsmq();
configurator.VerifyMsmqConfiguration();
configurator.UseMulticastSubscriptionClient();
configurator.ReceiveFrom("msmq://localhost/console");
configurator.Subscribe(x => x.LoadFrom(container));
});
container.Register(Component.For<IServiceBus>().Instance(bus));
}
}
我有一个ApiController
,其中包含以下GET操作方法
public class ExampleController : ApiController
{
private readonly IServiceBus _bus;
public HelloController(IServiceBus bus)
{
_bus = bus;
}
// GET api/hello?text={some text}
public Task<IBasicResponseCommand> Get(string text)
{
var command = new BasicRequestCommand {Text = text};
var tcs = new TaskCompletionSource<IBasicResponseCommand>();
_bus.PublishRequest(command, c =>
{
c.Handle<IBasicResponseCommand>(r =>
{
tcs.SetResult(r);
});
});
return tcs.Task;
}
}
BasicRequestCommand和BasicResponseCommand看起来像这样
public interface IBasicRequestCommand
{
Guid CorrelationId { get; set; }
string Text { get; set; }
}
public class BasicRequestCommand :
CorrelatedBy<Guid>, IBasicRequestCommand
{
public Guid CorrelationId { get; set; }
public string Text { get; set; }
public BasicRequestCommand()
{
CorrelationId = Guid.NewGuid();
}
}
public interface IBasicResponseCommand
{
Guid CorrelationId { get; set; }
string Text { get; set; }
}
public class BasicResponseCommand :
CorrelatedBy<Guid>, IBasicResponseCommand
{
public Guid CorrelationId { get; set; }
public string Text { get; set; }
}
处理程序响应控制台应用程序中的BasicRequestCommand:
public class BasicRequestCommandHandler : Consumes<IBasicRequestCommand>.Context
{
public void Consume(IConsumeContext<IBasicRequestCommand> context)
{
Console.Out.WriteLine("received message text " + context.Message.Text);
context.Respond(new BasicResponseCommand { Text = "Hello " + context.Message.Text, CorrelationId = context.Message.CorrelationId });
}
}
我期待所有这些在本地运行,请求/响应最多只有几秒钟。我在配置中遗漏了什么吗?
此外,我想将MassTransit挂钩到log4net。我正在使用Windsor的log4net日志记录工具,并在web.config中有一个log4net部分。对于Windsor提供的ILogger
实现(以及NHibernate日志记录),这一切都正常工作,但它是not clear from the documentation how to configure MassTransit to use this for logging。有什么想法吗?
答案 0 :(得分:4)
正如安德烈·沃尔科夫和克里斯·帕特森were discussing关于MassTransit google小组一样,这个问题似乎源于switching MassTransit使用SynchronizationContext
,由于某些原因,它不能按预期工作。
目前,一种解决方法似乎是转换为异步MassTransit请求,或者返回到不使用违规SynchronizationContext
的v2.1.1。
(如果没有其他人这样做的话,会在这里发布关于这个问题的后续更新。)
答案 1 :(得分:3)
ASP.NET中的请求/响应的响应超时问题在版本2.6.2中得到修复。 https://groups.google.com/d/topic/masstransit-discuss/oC1FOe6KsAU/discussion
答案 2 :(得分:1)
当您使用MultiCastSubscriptionClient时,必须在每台计算机上调用SetNetwork(NETWORK_KEY)
(使用相同的NETWORK_KEY值)。此外,所有参与的计算机都需要位于同一子网上 - 请参阅http://masstransit.readthedocs.org/en/latest/overview/subscriptions.html#msmq-multicast
对于连接log4net,它取决于您使用的版本,但在最新版本中,您包含MassTransit.Log4NetIntegration程序集,然后在服务总线配置中调用cfg.UseLog4Net();
。
如果您仍然卡住,可以在https://groups.google.com/forum/?fromgroups#!forum/masstransit-discuss
询问MT邮件列表