Rabbitmq-设计消息重播服务

问题描述:

我正在尝试设计一种重播机制,该机制将使用户能够重播队列中的消息. 对于包含多个队列和多个使用者的交换,我得出的最佳设计是:

I am trying to design a replay mechanism that will enable users to replay messages from the queues. The best design I have come up for an exchange that contains multiple queues and multiple consumers is:

  1. 创建一个记录器服务,该记录器将:

  1. Create a recorder service that will:

  • 创建一个队列并将所有路由键绑定到该队列.
  • 使用交易所的所有消息.
  • 将所有消息保存到数据库.

订户重播请求.

  • 每个订户创建一个新的交换,队列并使用与常规队列相同的绑定绑定到该交换.
  • 订户将休息请求发送到Web服务器,以使用过滤器(开始日期等)开始重播.请求包含其重播交换名称.
  • Web服务器从数据库中提取数据并将其发布到特定的交换机
  • 可以添加
  • 优化方法,例如附加RequestId并将其回显.

问题:
1.这有意义吗?
2.我是在发明轮子吗?有兔子固有的解决方案吗?插件?
3.创建多个交易所是否被视为一种好习惯?
在此解决方案中,将创建每个队列的交换以发布相同的消息.

Questions:
1. Does that make sense?
2. Am I inventing the wheel? Is there a rabbit inherent solution? plugin?
3. Does creating multiple exchanges considered a good practice?
In this solutionan exchange for each queue is created in order to publish the same message.

另一种解决方案:
1.为每个队列创建一个附加队列"ReplayQueue".设置TTL(比如说一个月).
2.每次用户请求重播时,请他从其自己的ReplayQueue中重播而不会确认.

Another solution:
1. Create an additional queue "ReplayQueue" for each queue. set a TTL (let's say a month).
2. Each time a user requests a replay let him replay from its own ReplayQueue without acking.

此解决方案有点问题,因为.

This solution is a bit problematic because.

  • 为了重播最后一天,消费者将必须提取所有早29天并将其过滤掉.
  • 此解决方案扩大规模-队列将变大(与可扩展的数据库存储不同).

  1. 这有意义吗?

  1. 我是发明轮子吗?有兔子固有的解决方案吗?插件?

您不是要重新发明轮子.没有AFAIK,没有兔子解决方案,也没有开箱即用的解决方案.

You are not reinventing the wheel. There is AFAIK no rabbit solution and no out of the box solution.

您认为您的第一个解决方案很好. Another solution非常有问题,因为健康的兔子是空的,兔子不是数据存储.

Your first solution is in my opinion good. The Another solution is very problematic, because a healthy rabbit is an empty one and rabbit is not a datastore.

您将有一个队列(STORE),所有已发布的消息都应被路由到该队列.您可以考虑使用主题交换,而不是将STORE与所有绑定键绑定.以这种价格,绑定密钥不得包含. # *以及路由消息时的少量开销. STORE队列将与绑定键#绑定.

You will have a queue (STORE) where all published messages should be routed to. Instead of binding STORE with all the binding keys, you could consider using a topic exchange. At the price that binding key must not contain . # * and a slight overhead when the message is routed. The STORE queue will bind with the binding key #.

您可以查看 firehose .

为什么要提出网络请求?您可以将Rabbit与 RPC调用一起使用:

Why a web request? You can use Rabbit with an RPC call:

  • 订户发送一个amqp请求,以使用过滤器(startdate等)开始重播.
  • 请求包含reply-to队列名称.队列可能不属于客户端和请求.
  • RPC服务器从数据库中提取数据并将其发布到答复队列
  • Subscriber sends an amqp request to start replay with a filter ( startdate, etc).
  • Request contains the reply-to queue name. The queue may be exclusive to the client and request.
  • RPC server pulls data from the DB and publishes it to the reply-to queue

您还可以查看直接答复模式.

  1. 创建多个交换是否被认为是一种好习惯?

是的,只要您需要它.对于您的特定情况,我认为没有必要按订户进行交换.该请求已包含队列名称.您可以简单地使用默认交换amq.direct将其发布到此队列,并且路由键等于队列名称.如果要进行交换,我将创建一个唯一的交换(例如重播"),并让每个订阅者将其重播队列绑定到此交换. 重播"交换可以是约定的,也可以与请求一起发送.

Yes, as soon as you need it. For your specific case, in my opinion an exchange per subscriber is not necessary. The request contains already the queue name. You could simply publish to this queue using the default exchange amq.direct with the routing key equal to the queue name. If you want an exchange I would create an unique exchange (eg. "replay") and have each subscriber bind their replay queues to this exchange. The "replay" exchange can be a convention or sent with the request.