RabbitMQ 使用自定义 headers 来存储 message-parameters

RabbitMQ using custom headers to store message-parameters

我是 RabbitMQ 的新手,我有点迷失在文档中。

目前,举个例子,我正在尝试构建一个小型 mailer-service 来监听 queue,但我有点卡在应该将我的服务的参数放在哪里有(目的地,主题,...)

我应该将它们放入某种编码格式 (json) 中,放在我的消息中,还是应该使用 header-construction,如下例所示:

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

使用 headers 是否提供额外的好处?例如,是否可以过滤发送到特定目的地的消息?

我不会用 headers 来做你想做的事情。在我看来,该信息属于消息的 body。

这样看:

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

另一方面,

Headers 是有关 AMQP 消息的数据位,而不是消息内容。

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

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

在这种情况下,您通过 rabbitmq 发送的消息将包含一些内容,例如预先计算多少斐波那契数位,然后再发送多少斐波那契。

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

{
  start: 1,
  take: 3
}

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

根据您的具体问题和逻辑:我应该将 starttake 属性放入消息的 header 中吗?

没有。

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

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

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

在这种情况下,我是说我想要 return 斐波那契数列中的项目。换句话说,我正在参与 RPC(远程过程调用)并期待 return 值。

AMQP 不直接支持 return 值。然而,我能做的是将 queue 名称填入 header 并将结果发送给 queue。然后请求斐波那契数的代码可以收听 queue 并获得结果。

所以我可能会在发送消息时做这样的事情:

var properties = new BasicProperties();
properties.Headers = new Dictionary();
properties.Headers.Add("return-queue", "fibreturn");

我在这里设置了一个 "return-queue" header - 关于消息的信息,或者在这种情况下请求信息 - 在 header 中。处理斐波那契数列的代码将读取此 header 并将响应发送回此 queue.

这是 header 的更好用法,因为它使 header 存储有关消息的信息...在这种情况下,应将响应发送到哪里。但是,headers 不包含有关要完成的实际工作的信息。也就是直接存储在消息body中。


P.S。我故意不使用 "reply-to" 属性 ,就像你通常应该做的那样,做 RCP。我用这个作为一个例子来说明为什么你不应该把你的 "destination" 放在 header 中。为了更好地实现斐波那契数列的想法,请参阅 RMQ 文档以及它如何正确使用 "reply-to" https://www.rabbitmq.com/tutorials/tutorial-six-dotnet.html