RabbitMQ使用自定义标头来存储消息参数 [英] RabbitMQ using custom headers to store message-parameters

查看:602
本文介绍了RabbitMQ使用自定义标头来存储消息参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是RabbitMQ的新手,在文档中有些迷路.

当前,以一个示例为例,我试图构建一个侦听队列的小型邮件服务.但是我在应该将服务的参数(目标,主题等)放置在何处

我应该将它们放入消息中的某种编码格式(json)中,还是应该使用标头构造,例如以下示例:

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

使用标头还会带来其他好处吗?例如,是否有可能过滤发送到特定目标的邮件?

解决方案

我不会为要执行的操作使用标题.我认为这些信息属于消息的正文.

这样看:

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

另一方面,标头是有关AMQP消息的数据位,而不是消息内容.

在这里,通过电子邮件"来完成您的工作有很多潜在的困惑. AMQP消息和电子邮件消息之间的术语重叠太多.

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

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

例如,您可能会发送这样的消息(在这种情况下为json):

{
  start: 1,
  take: 3
}

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

使用您的特定问题和逻辑:我应该将starttake属性放入消息的标题中吗?

不.

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

当我这样看时,这没有任何意义,因为现在没有消息可发送了……只有标题.

另一方面,如果我将这两点数据保留在消息正文中,则标头将变得更加有用,可以作为发送有关AMQP消息本身的元数据的方式……不是有关消息内容的信息,而是有关消息提示的信息.

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

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

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

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

在这里,我要在标题内设置返回队列"标题-有关消息的信息,或在这种情况下要求提供信息.处理斐波那契序列的代码将读取此标头,并将响应发送回此队列.

这是对标头的更好使用,因为它使标头存储有关消息的信息...在这种情况下,应将响应发送到此位置.但是,标头不包含有关要完成的实际工作的信息.这些都直接存储在消息正文中.


P.S.我故意不像通常那样使用回复"属性来进行RCP.我以此为例说明为什么不应该将目标"放在标题中.有关斐波那契序列概念的更好实现,请参阅RMQ文档及其正确使用回复"的方法 https://www.rabbitmq.com/tutorials/tutorial-six-dotnet.html

I'm new to RabbitMQ, and I'm somewhat lost in the documentation.

Currently as an example I'm trying to build a small mailer-service that listens to a queue. But I'm somewhat stuck on where I should put the parameters that my service has (destination, subject, ...)

Should I put them inside some encoded format (json), inside my messages, or should I use the header-construction, like the following example:

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

Does using the headers offer additional benefits? Like for example would it be possible to filter messages that are send to a specific destination?

解决方案

I wouldn't use headers for what you are trying to do. That information belongs in the body of the message, in my opinion.

Look at it this way:

The body of the message should contain everything you need to complete the work requested. In this case, it would be the sender, subject, email content, etc.

Headers on the other hand, are bits of data about the AMQP message, not the message contents.

There's a lot of potential confusion here with your work to be done being "email". Too much overlap in terminology between the AMQP message, and email message.

That being said, I'll pick a different example of work to do: calculate the fibonacci sequence.

In this case, the message you send across rabbitmq would contain something like how many places of fibonacci to calculate up front and then how many to send back, after that.

For example you might send a message like this (as json in this case):

{
  start: 1,
  take: 3
}

This should produce a result of 1, 1, 2 because it starts at the first position and returns 3 items from the sequence.

Using your specific question and logic: should I put the start and take attributes into headers of the message?

No.

If I did, that would mean my message is empty as all of the information about the work to be done would be contained in the headers.

It doesn't make sense when I look at it this way because now there is no message to send... only headers.

On the other hand, if I keep these two points of data in the message body, the headers become more useful as a way to send metadata about the AMQP message itself... Not information about the content of the message, but information about the idea of the message.

In this case I'm saying that I want to return items from the fibonacci sequence. In other words, I'm engaging in RPC (remote procedure call) and am expecting a return value.

AMQP doesn't support return values directly. What I can do, however, is stuff a queue name into the headers and send the result to that queue. Then the code that requested the fibonacci numbers can listen to that queue and get the results.

So I might do something like this when sending the message:

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

Here I'm setting up a "return-queue" header - information about the message, or request for information in this case - inside of the headers. The code that handles the fibonacci sequence will read this header and send the response back to this queue.

This is a better use of headers, as it makes the header store information about the message... In this case, where the response should be sent. The headers don't contain information about the actual work to be done, though. That is all stored in the message body directly.


P.S. I am purposely not using the "reply-to" property like you normally should, to do RCP. I'm using this as an example of why you shouldn't put your "destination" in the headers. For a better implementation of the fibonacci sequence idea, see the RMQ docs and how it uses "reply-to" correctly https://www.rabbitmq.com/tutorials/tutorial-six-dotnet.html

这篇关于RabbitMQ使用自定义标头来存储消息参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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