当前位置: 首页 > 知识库问答 >
问题:

为了确保并发性,同一组在多个队列中工作(FIFO)

尤茂材
2023-03-14

我有一个关于多使用者并发的问题。我想发送工作到rabbitmq来自web请求到分布式队列。我只想确定多队列中的工作顺序(FIFO)。因为此请求来自不同的用户,所以必须对eech用户请求/工作进行排序。

我已经在Azure ServiceBus和ActiveMQ消息分组上发现了这个具有不同名称的特性。

我想保证客户的要求必须相互订购。每个客户可能有多个请求,但必须按顺序处理针对该客户的请求。我希望在不同节点上使用多个使用者来快速处理传入请求。例如,不同的客户1到1000发送的请求超过1百万。如果我将这个巨大的请求只放在一个队列中,它将花费大量的时间。所以我想在n(5)个节点之间分担这个进程负载。对于客户X的请求必须按照相同的顺序进行处理

共有1个答案

寇夜洛
2023-03-14

在使用基于事件的系统时,特别是在使用多个生产者和/或消费者时,必须了解这样一个事实,即通常不存在事件的保证顺序。为了得到一个健壮的系统,明智的做法是将系统设计成消息处理程序是幂等的;他们应该容忍两次(或更多次)得到相同的信息。

有很多事情可能(而且实际上应该被允许)干扰秩序;

  • 制作者传递消息的速度可能略有不同
  • 一个生产者可能错过了ack(由于错过了包),并将重新发送消息
  • 一个使用者可能获得并处理一条消息,但返回的途中丢失了ack,因此该消息被传递了两次(给另一个使用者)。
  • 您的处理程序依赖的某些其他服务可能已关闭,因此您必须拒绝该消息。

话虽如此,ServiceBus(像NServicebus这样的系统)使用一种模式来强制使用订单消息。有一些要求:

  • 您将需要一个允许有条件更新的集中存储(如sql-server或文档存储);例如,您希望能够存储上次处理的消息的序列号(或者您在该过程中已经完成了多长时间),但前提是已经存储的序列/进度是正确的/预期的序列/进度。存储用户ID和进度,即使是数百万客户也应该是大多数数据库非常容易的操作。
  • 确保为重试配置了死信队列/交换队列,然后再次将原始队列设置为该队列的死信队列。
  • 您在retry/dead-letter-queue上设置了一个TTL(例如30秒)。这样,死信队列中出现的消息将在超时后自动推回到原始队列。
  • 处理消息时,检查存储/数据库是否处于处理消息的正确状态(即前面所需的步骤已经完成)。
    • 如果您可以处理它,请执行并更新存储(有条件地!)。
    • 如果不是-您将消息nack,以便将其抛出到死信队列中。基本上您说的是“不--我无法处理此消息,队列中可能有其他消息应该首先处理”。

    这种方式的快乐路径是以正确的顺序处理大量的消息。但是如果发生了一些事情,并且您得到了一个带外的消息,您将把它扔到重试队列(死信队列)中,并且Rabbit将确保它将返回队列以便在稍后的阶段重试。但只是在一段时间后。

    这样做的好处在于,您能够以完全相同的方式处理可能干扰消息处理的大多数情况(无序消息、依赖服务关闭、处理程序在处理消息过程中关闭);通过拒绝消息并让您的基础结构(Rabbit)处理一段时间后的重试。

 类似资料:
  • 问题内容: 我正在寻找java.util.Queue或Google集合中某些行为类似于Queue的实现,但还要确保队列中的每个元素都是唯一的。(所有进一步插入均无效) 有这种可能,还是我必须手工完成? 现在,我正在使用带有LinkedList实现的Queue,并在插入之前检查其唯一性。(我使用侧面地图进行此操作,在排队之前/之后在侧面地图中添加/删除元素)。我不太喜欢 欢迎任何输入。如果它不在ja

  • 我目前正在尝试使用RabbitMQ(具有出色的RabbitMQBundle)来处理大量的异步工作。 目标是让一个队列发布相同类型的消息,并让多个服务器上的X个工作者在同一时间内查看消息。 每个工人都要偷看一条消息,完成工作,然后偷看另一条消息,等等。 这里是我的conf: 在我的consumer中,我有一个日志文件中的条目和120秒的睡眠。 我启动了php app/console rabbitmq

  • 我想知道,在Spring AMQP中,是否可以根据负载类型在多个类中接收来自同一队列的消息。 我知道在类中使用@RabbitListener注释,然后将@RabbitHandler放在方法上,但我希望在保持单个队列的同时将消息处理的复杂性拆分为多个类。 当前使用的版本:Spring AMQP v2.0.3以及RabbitMQ。

  • 我有一个应用程序,它发送电子邮件和执行文件上传(和图像大小调整)。这两种服务都不经常使用,而且都很轻。 让两个ec2实例坐在那里(在大多数情况下)什么都不做似乎非常浪费。 PS:我用的是弹性豆茎

  • 我知道如何复制工作表,但这将导致多个工作表。我需要的是一个输出工作表,一个接一个地包含所有的工作表。 目前我正在做的是将每个工作表导出为< code>DataTable,然后逐个导入: 但这样,我就失去了单元格样式和文本格式 有没有办法用保留样式?

  • 我有一个Excel工作簿,其中包含36个不同的工作表,我每两周收到一次,工作表在所有标签上都有共同的标题,并且每个标签上都有不同的唯一标题,但每条记录都有一个唯一的ID,可以有多个记录。 我要做的是从所有的工作表中提取唯一的id,然后将每个工作表中的数据提取到一个工作表中,其中包含所有的公共标题和唯一标题。 我正在考虑使用下面帖子中的代码将其导入Access。连接表并将其导出回Excel中的一个工