MassTransit 2.6.1请求/响应模式-响应超时 [英] MassTransit 2.6.1 Request/Response pattern - Response times out

查看:93
本文介绍了MassTransit 2.6.1请求/响应模式-响应超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将MassTransit作为ServiceBus实现在Web项目中使用.

I'm looking at MassTransit as a ServiceBus implementation to use in a web project.

我正在使用请求/响应模式消费者收到消息并做出响应与请求发布者处理响应之间存在很长的延迟;有时,似乎永远都不会通过响应(将其运行10分钟后,仍然没有通过).我唯一看到响应响应调用了委托委托的时间是在30秒的超时时间之后,并且抛出了超时异常.在这种情况下,将碰到在处理程序委托上设置的断点.

I am playing with the Request/Response pattern and am seeing a long delay between the consumer receiving the message and responding, and the request publisher handling the response; sometimes, it seems like the response is never going to come through (having left it running for 10 minutes, the response has still not come through). the only times that I have seen the handle delegate get called with the response is after a 30 second timeout period and the timeout exception being thrown; in this situation, the breakpoint set on the handler delegate is hit.

该设置是标准操作-我有一个发布应用程序的Web应用程序,一个消费请求并发送响应的控制台应用程序,供该Web应用程序处理回调中的响应.

The setup is a standard affair - I have a web app that is publishing requests, a console app that is consuming requests and sending responses, for the web app to handle the responses in the callback.

我正在使用温莎城堡,并且使用WebActivator在Web项目中初始化了容器:

I'm using Castle Windsor, and the container is initialized in the web project using WebActivator:

[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看起来像

In the web app project (an ASP.NET Web API project), the WindsorInstaller for MassTransit looks like

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看起来像

In the console app project, the WindsorInstaller looks like

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操作方法

I have an ApiController with the following GET action method

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看起来像这样

BasicRequestCommand and BasicResponseCommand look like so

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:

And the handler responding to the BasicRequestCommand in the console app:

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 });
    }
}

我期望所有这些都在本地运行,因此请求/响应最多只有几秒钟的时间.我在配置中缺少什么吗?

I was anticipating with all of this running locally that the request/response would be in the order of a few seconds at most. Am I missing something in configuration?

此外,我想将MassTransit连接到log4net.我正在使用Windsor的log4net日志记录工具,并且在web.config中有一个log4net部分.对于Windsor提供的ILogger实现(以及NHibernate日志记录),这一切都很好,但是它是在文档中不清楚如何配置MassTransit以将其用于日志记录.有什么想法吗?

In addition, I wanted to hook MassTransit up to log4net. I am using Windsor's log4net logging facility and have a log4net section in web.config. This is all working fine for ILogger implementations provided by Windsor (and also for NHibernate logging), but it's not clear from the documentation how to configure MassTransit to use this for logging. Any ideas?

推荐答案

就像安德烈·沃尔科夫(Andrei Volkov)和克里斯·帕特森(Chris Patterson)

Just as Andrei Volkov and Chris Patterson were discussing on MassTransit google group, it seems that this issue stems from switching MassTransit to using SynchronizationContext, which for some reason does not work as expected.

目前,一种解决方法似乎是过渡到异步MassTransit请求,或者回到不使用有问题的SynchronizationContext的v2.1.1.

For the time being one workaround seems to be transitioning to async MassTransit requests, or going back to v2.1.1 that does not use the offending SynchronizationContext.

(如果没有其他人先这样做,将在此处发布有关此问题的最新信息.)

这篇关于MassTransit 2.6.1请求/响应模式-响应超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆