如何使用EasyNetQ从RabbitMQ同步使用原始字节消息?

时间:2015-11-17 20:46:33

标签: c# .net rabbitmq messaging easynetq

有没有办法使用EasyNetQ从RabbitMQ同步使用原始字节消息?

我需要保证对来自未以EasyNetQ格式发布的系统的消息进行有序处理和调整。我知道消费者在一个线程上运行,但IAdvancedBus接口只提供一种消耗原始消息的方法:

IDisposable Consume(IQueue queue, Func<byte[], MessageProperties, MessageReceivedInfo, Task> onMessage);

Task返回类型意味着使用者异步运行回调,因此可能无序处理消息。

如果没有,是否有任何更改代码以支持此功能的想法?我会制作接口方法:

IDisposable Consume(IQueue queue, Action<byte[], MessageProperties, MessageReceivedInfo> onMessage);

并在RabbitAdvancedBus中实现它,但我不确定代码的确切位置。

2 个答案:

答案 0 :(得分:0)

这是一个有趣的问题。我自己也不是EasyNetQ专家,也许其他人会来并给你一个更好的答案。 然而我已经熟悉EasyNetQ code base大约一年了,在我看来,了解消费者接线时发生的事情是很棘手的(因此在调用消费者时)。

我首先要指出的是,只是通过更改方法的签名,无法保证按顺序处理消息。请查看建议界面的此实现示例:

IDisposable Consume(IQueue queue, Action<byte[], MessageProperties, MessageReceivedInfo> onMessage)
{
    Func<byte[], MessageProperties, MessageReceivedInfo, Task> taskWrapper = (bytes, properties, info) =>
    {
        onMessage(bytes, properties, info);
        return new Task(() => { });
    };
    Consume(queue, taskWrapper);
}

它调用原始的Consume方法,我们真的不知道之后会发生什么,对吗?

如果我在哪里穿上鞋子,我会做以下事情之一:

  1. 使用Official RabbitMq Client并在那里使用消息(这不是那么棘手!)
  2. 或许看看RawRabbit,这是我在RabbitMq上面的一个薄层(我使用vNext标准)。它只支持消费消息的异步签名,但是编写Subscriber.cs的同步实现并不困难(使用像AsyncEx这样的同步库。)
  3. 更改业务逻辑的建模。我不确定这是否适用于您的情况,但一般来说,如果每个消息都按正确顺序处理是关键任务,那么您应该以某种方式对其进行建模,以便使用者方法可以验证此消息是下一个。 (此外,我不认为EasyNetQ可以保证消息序列,因此您可能希望为每个新版本的框架验证它。)
  4. 希望这有帮助!

答案 1 :(得分:0)

我收到了一份适用于EasyNetQ Google Group的回复:

要同步执行,您可以执行以下操作:

var_dump($row_percent[130]);

或添加扩展程序:

bus.Advanced.Consume(queue, (bytes, properties, info) =>
{
    // do your synchronous work.....
    return Task.CompletedTask;
});

更新:此功能已在0.52.0.410版中添加:

https://github.com/EasyNetQ/EasyNetQ/pull/505