【问题标题】:Mechanism for reading all messages from a queue in one request在一个请求中从队列中读取所有消息的机制
【发布时间】:2019-05-08 05:59:47
【问题描述】:

我需要一个类似于队列的以下场景的解决方案:

我想将消息连续写入队列。我的信息很大,包含大量数据,所以我确实希望尽可能少地提出请求。 所以我的队列会在某个时候包含很多消息。 我的消费者将每 1 小时从队列中读取一次。 (不是每当写入新消息时),它将读取队列中的所有消息。

问题是我需要一种方法来仅使用一次调用从队列中读取所有消息(我还希望消费者向队列发出尽可能少的请求)。

一个接近的解决方案是 ActiveMQ,但问题是您一次只能读取一条消息,而我需要在一个请求中读取它们。

所以我的问题是.. 还有其他方法可以更有效地做到这一点吗?我需要的实际事情是以某种方式持久保存由某个应用程序连续创建的消息,然后每 1 小时由同一个应用程序一次性使用它们(也删除它们)。

我认为队列适合的原因是,当消息被消费时,它们也会被删除,但我需要一次性消费它们。

【问题讨论】:

  • 您每小时消耗多少条消息?它们需要按顺序食用吗?客户端应用在消费消息时做了哪些处理工作?它是否需要大量资源(例如 CPU、磁盘、内存等)?请详细说明。
  • 我举个例子:应用程序是一个在线商店。每个产品都有一个品牌。管理员可以更改所有具有某个品牌的产品的价格。(所以将价格更改为 10.000产品,例如一次)。所有这些产品的信息都发生了变化,因此它们需要在外部商家上更新,所以我需要将它们临时存储在某个地方。每小时我拿这些产品并和他们一起打电话给外部商家。之后每次调用都应该删除它们。现在,为每个要更新的产品创建一个对象,然后在 DB 的另一个表中删除一个对象,这效率不高。
  • 所以另一种方法是使用队列,但要花费大量时间来编写每条消息的 10.000 个请求和读取 10.000 个请求。
  • “呼叫外部商家”到底涉及什么?那是 HTTP 请求、REST 微服务等吗?您是否担心增加应用程序的吞吐量可能会使“外部商家”不堪重负?
  • 另外,您是否确定需要一种比 ActiveMQ 代理(无论是 5.x 代理还是较新的 Artemis 代理)更有效地解决此问题的方法?你用 ActiveMQ 测试过吗?如果是这样,结果如何?您需要什么性能数据?

标签: java queue activemq message-queue producer-consumer


【解决方案1】:

我认为在您寻找解决方案时需要牢记一些重要的事情:

  1. 您需要以何种方式“提高效率”(例如时间、金钱成本、计算资源等)?
  2. 事实上,很难证明没有其他“更有效”的方法可以解决特定问题,因为这需要测试所有可能的解决方案。您真正需要知道的是,根据您的特定用例,什么解决方案足够好。当然,这需要具体了解您需要什么样的性能数据以及获取这些数据的限制条件(例如时间、金钱成本、计算资源等)。
  3. 现代消息代理客户端(例如,那些附带 ActiveMQ 5.x 或 ActiveMQ Artemis 的客户端)不会为它们使用的每条消息进行网络往返,因为那样效率极低。相反,它们以可配置的大小获取消息块(例如,prefetchSize 用于 ActiveMQ 5.x,consumerWindowSize 用于 ActiveMQ Artemis)。这些消息在本地存储在各种缓冲区中,并在进行相关 API 调用以接收消息时提供给客户端应用程序。
  4. “尽可能少地请求”很少能提高性能。现代消息代理可以很好地与并发消费者一起扩展。与启动多个线程相比,单个消费者使用所有消息极大地限制了消息吞吐量,每个线程都有自己的消费者。与其限制消费者请求的数量,您几乎肯定应该将它们最大化,直到达到收益递减点。

【讨论】:

    猜你喜欢
    • 2012-09-03
    • 2021-03-11
    • 2019-09-27
    • 1970-01-01
    • 2013-12-13
    • 2013-12-18
    • 1970-01-01
    • 2017-01-17
    • 2014-11-08
    相关资源
    最近更新 更多