RabbitMQ 使用自定义 header 来存储消息参数

标签 rabbitmq messaging

我是 RabbitMQ 的新手,我在文档中有些迷失。
目前,作为一个例子,我正在尝试构建一个监听队列的小型邮件服务,但我有点不知道应该把我的服务的参数放在哪里(目的地、主题……)
我应该将它们放在某种编码格式 (json) 中,放在我的消息中,还是应该使用 header 构造,如下例所示:

string message = "Hello World!";
var body = Encoding.UTF8.GetBytes(message);

var properties = new BasicProperties();
properties.Headers = new Dictionary<string, object>();
properties.Headers.Add("destination", "matthias123@localhost");

channel.BasicPublish(exchange: "", routingKey: "sendmail", basicProperties: properties,body: body);
使用标题是否提供额外的好处?例如,是否可以过滤发送到特定目的地的消息?

最佳答案

我不会将标题用于您要执行的操作。在我看来,该信息属于消息正文。

这样看:

消息正文应包含完成请求的工作所需的一切。在这种情况下,它将是发件人、主题、电子邮件内容等。

另一方面, header 是有关 AMQP 消息的数据位,而不是消息内容。

这里有很多潜在的混淆,因为您要完成的工作是“电子邮件”。 AMQP 消息和电子邮件消息之间的术语重叠太多。

话虽如此,我将选择一个不同的工作示例:计算斐波那契数列。

在这种情况下,您通过 rabbitmq 发送的消息将包含诸如要预先计算多少个斐波那契位置,然后再发送多少个位置之类的信息。

例如,您可能会发送这样的消息(在本例中为 json):

{
  start: 1,
  take: 3
}

这应该产生 1, 1, 2 的结果因为它从第一个位置开始并从序列中返回 3 个项目。

使用你的具体问题和逻辑:我应该把 starttake属性到消息的标题?

不。

如果我这样做了,那将意味着我的消息是空的,因为有关要完成的工作的所有信息都将包含在标题中。

当我这样看时没有意义,因为现在没有消息要发送......只有标题。

另一方面,如果我将这两个数据点保留在消息正文中,则 header 作为发送有关 AMQP 消息本身的元数据的方式变得更加有用......不是有关消息内容的信息,而是有关消息的信息消息的想法。

在这种情况下,我是说我想从斐波那契数列返回项目。换句话说,我正在使用 RPC(远程过程调用)并期待返回值。

AMQP 不直接支持返回值。但是,我可以做的是将队列名称填充到标题中并将结果发送到该队列。然后请求斐波那契数列的代码可以监听该队列并获得结果。

所以我在发送消息时可能会做这样的事情:
var properties = new BasicProperties();
properties.Headers = new Dictionary();
properties.Headers.Add("return-queue", "fibreturn");

在这里,我正在设置一个“返回队列” header - 有关消息的信息,或在这种情况下的信息请求 - 在 header 内。处理斐波那契数列的代码将读取此 header 并将响应发送回此队列。

这是对 header 的更好使用,因为它使 header 存储有关消息的信息……在这种情况下,应将响应发送到何处。但是,标题不包含有关要完成的实际工作的信息。那都是直接存储在消息正文中的。

附言我故意不使用您通常应该使用的“回复”属性来执行 RCP。我以此为例说明为什么不应该将“目的地”放在标题中。为了更好地实现斐波那契数列的想法,请参阅 RMQ 文档以及它如何正确使用“回复”https://www.rabbitmq.com/tutorials/tutorial-six-dotnet.html

关于RabbitMQ 使用自定义 header 来存储消息参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42593804/

相关文章:

java - 使用 stdin-channel-adapter 的 spring 集成类是什么?

java - 使用 JMS 向 RabbitMQ 发送消息

java - rabbitMQ 读取一个值也会从队列中刷新其他值

python - 如何将一系列任务路由到 celery 中的特定队列?

c# - 在 C++ 和 C# 应用程序之间进行异步通信的最简单方法是什么

java - 同步和合并消息/数据流

java - 线程: Shared Resource special situation

php - 如何从php上传文件到amqp

messaging - 如何确保多个竞争消费者的消息幂等性?

mysql - 消息表,不向已删除的人显示消息