【问题标题】:MessageBus: wait when processing is done and send ACK to requestorMessageBus:等待处理完成并向请求者发送ACK
【发布时间】:2018-08-01 19:11:02
【问题描述】:

我们使用外部 TCP/IP 接口,其中一项要求是保持连接打开,等待处理完成,然后将结果发送回 ACK。

假设我们想要使用 MessageBus (masstransit/nservicebus) 与处理模块通信并跟踪消息状态:接收、处理、成功、失败,那么实现这一目标的最佳方法是什么?

具体来说,当消息到达处理程序/消费者时,它如何知道 TCP/IP 连接?我应该将它存储在某个自定义容器中并将其注入消费者吗?

感谢任何指导。谢谢。

【问题讨论】:

  • TCP/IP连接是用来监控NServiceBus中消息处理状态的理解正确吗?
  • 为什么需要保持连接打开?
  • @HadiEskandari,当消息来自外部接口时,它会触发某些操作,例如“创建订单”。它期望确认订单是通过相同打开的 TCP/IP 连接创建还是失败。不幸的是,它不支持延迟的后续响应。这些界面是 30 年前设计的,我们无法更改它们......

标签: nservicebus masstransit


【解决方案1】:

消费者将知道如何启动和管理 TCP 连接生命周期。

当接收到消息时,处理程序可以调用代码,该代码根据消息数据执行某些操作。这是否涉及在某处的屏幕上显示绿色大象或打开端口、拨打电话、然后处理 ACK,都不会改变您处理消息的方式。

负责执行操作的实际代码可以打包成类似 nuget 包的东西,并暴露在某种通用接口上,如果这能让你更开心的话,但与具有双重角色的组件没有矛盾该消息的消息使用者和处理器。

将为每条消息创建一个新的消费者实例 接收。此外,在我的情况下,消费者无法启动 TCP/IP 连接,它已经在早些时候打开(并存储在某个地方 else) 并且消费者只需有权使用它。

对不起,我应该更仔细地阅读你原来的问题。

有一个从 NServiceBus 共享访问资源的解决方案,如文档 here 所述。

public class SomeEventHandler : IHandleMessages<SomeEvent>
{
    private IMakeTcpCall _caller;

    public SomeEventHandler(IMakeTcpCalls caller)
    {
        _caller = caller;
    }

    public Task Handle(SomeEvent message, IMessageHandlerContext context)
    {
        // Use the caller 
        var ack = _caller.Call(message.SomeData);

        // Do something with ack
        ...

        return Task.CompletedTask;
    }
}

理想情况下,您应该有一个 DI 容器,它将 IMakeTcpCall 实例的生命周期作为单例来管理(尽管这在大容量场景中可能会变得很奇怪),这样您就可以重新使用打开的TCP 通道。

例如,Castle Windsor:

Component.For<IMakeTcpCalls>().ImplementedBy<MyThreadsafeTcpCaller>().LifestyleSingleton();

Castle Windsor integrates 与 NServiceBus

【讨论】:

  • 每收到一条消息都会创建一个新的消费者实例。此外,在我的例子中,消费者无法启动 TCP/IP 连接,它已经在早些时候打开(并存储在其他地方),消费者只需要有权使用它。听起来应该将此信息注入消费者(as suggested by Chris Patterson here)。
  • 谢谢,这是有道理的。就我而言,我将不得不使用 MassTransit 和 Autofac。我确信那里支持类似的功能。
猜你喜欢
  • 2017-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多