【问题标题】:How do I get multiple clients to listen to the same consumer?如何让多个客户听同一个消费者?
【发布时间】:2016-12-20 22:36:42
【问题描述】:

例如,生产者 A 在队列/通道上将消息传递给消费者 A。假设它是体育比分。

如何让多个客户端(台式机、移动设备等)监听或连接到消费者 A?这样做的最佳选择是什么?

我问的是与底层消息代理无关的问题。

【问题讨论】:

  • 多播。 rabbitmq中的“交换”
  • 使用 Kafka 的多个客户端(消费者)可以在不同的组中获取自己的消息副本。
  • 我的问题更像是“如果出租车应用程序必须向所有出租车司机发送消息(相同的消息),假设给定城市中有 10,000 人,所有出租车司机都会订阅同一个消费者?
  • @Jon 您的术语已关闭。没有任何东西订阅消费者。消费者是订阅交换的人(至少在rabbitmq中)。你需要的是一个扇出交换,基本上就是 AdamSkywalker 所指出的,他只是使用了多播这个词。

标签: java rabbitmq apache-kafka message-queue messaging


【解决方案1】:

生产者 A 将队列/通道上的消息传递给消费者 A

在 Apache Kafka 中,我们谈论的是一个“主题”。

我的问题更像是“如果出租车应用程序必须向所有出租车司机发送消息(相同的消息),假设某个城市有 10,000 名出租车司机,那么所有出租车司机都会订阅同一个消费者吗? ?

假设我们正在讨论一款所有出租车司机都在使用的 Android 应用。

我的假设:

  1. 我在回答中所说的“消费者”是指服务器/节点,它使用来自某些消息代理的特定队列/主题的消息,例如来自 RabbitMQ 或 Apache Kafka。

  2. 使用的每条消息都包含一条业务消息,应交付给所有 10 000 个驱动程序,例如“市中心有警察控制”。

  3. 我假设商务消息一天要发送几次,所以当司机一天离线时,他会在登录后收到几条消息。

  4. 我假设每个驱动程序(客户端)都有一个唯一的 ID。

  5. 我假设通信是通过 HTTP 进行的,例如每个客户端(10k 出租车中的每个应用程序)都在发出 HTTP 请求,例如每 30 秒到服务器检查是否有一些新消息。请求中提供了客户端的 ID(一些身份验证也是必须的,但这与此处无关)。因此,如果有 10k 个客户端,那么如果所有驱动程序都在线,那么平均每秒向服务器发送大约 333 个请求。

可能的解决方案:

  1. 服务器消耗所有消息并将它们保存在一些快速存储中,例如memcached 或 redis。

  2. 同时,服务器为所有 10k 驱动程序保留有关特定驱动程序收到的最后一条消息的信息。如上所述,这也应该存储在一些快速存储中。

可能的情况:

假设过去 24 小时内有 20 条消息,每条消息的 ID 为 1 到 20。

  1. ID = 517 的客户端正在向 server.com/message/517 发出 HTTP 请求。
  2. 服务器正在缓存中检查发送给驱动程序 517 的最后一条消息是什么。假设他的最后一条消息是消息 18。
  3. 服务器正在发送驱动程序消息:19 日和 20 日。
  4. 服务器正在缓存中存储驱动程序 517 的最后一条消息是 20。 5. 之后例如30 秒后,同一客户端发出下一个请求,但由于驱动程序已收到所有消息,因此发送回的消息为零。

总结

总结一下你需要在机器里存储:

  1. 10k 驱动程序中每个驱动程序的进度/位置。
  2. 20 条消息。

这是您正在寻找的答案吗?

【讨论】:

  • 我非常感谢您的回复,但在这里我仍然有点困惑。看一下rabbitmq的扇出示例。 rabbitmq.com/tutorials/tutorial-three-java.html ,您可以看到每个消费者如何接收相同的消息。让我们将其应用于出租车应用程序。你会有 10,000 个队列连接到这个生产者吗?或者只有一个消费者,然后所有 10,000 名出租车司机都从该消费者那里接收信息。
  • (1) 不,您不会有 10k 队列连接到生产者。 (2) 是的,只有一个消费者,然后所有 10k 出租车司机都从该消费者那里接收信息。大图:您将有 1 个生产者将消息流式传输到 1 个队列中。然后,您将有 1 个消费者使用该单个队列中的所有消息。这个单一消费者将是您数据中心中的一个节点(服务器)(或 VPS,或 Docker 容器,并不重要)。然后,您将在出租车中拥有 10k 台设备,这些设备将与您数据中心中的单个消费者节点连接。
  • 谢谢,这就是我想澄清的。一旦数据最终被消费和存储,你认为什么最适合连接数据?它会类似于计时器上的 ajax 请求吗?
  • @Jon “你认为什么最适合连接数据一次......”:是的,其中一个选项是 HTTP 请求(例如,如果这是来自浏览器的 ajax)。也有网络套接字。但这是另一个我无法胜任的问题,它取决于您的用例、您的客户端(浏览器、android 等),因此您需要进行额外的研究和决定。正如 Martin Fowler 经常说的:“编程是关于权衡的”。如果我帮助了你,我很高兴,至少一点点:)干杯!
  • "服务器正在缓存中检查发送给驱动程序 517 的最后一条消息是什么。假设他的最后一条消息是消息 18。" - redis 是否提供支持,例如上次检查某事的时间?怎么做呢?
【解决方案2】:

如果您使用的是 web/servlet 容器,则可以使用 pub/sub JMS。

或者现在你可以看到 web-sockets,这可以为你提供全双工通信.. 在互联网上搜索 web-sockets..

【讨论】:

    【解决方案3】:

    Kafka 有一个消费者组的概念,如果你有一个主题 A 和 3 个消费者 A1、B1、C1,并且你想创建传递到主题 A 的消息副本,并发送到 A1、B1 和 C1,那么启动三个消费者3 个不同的消费群体。

    查看Kafka Article on javaworld了解消费者组的详细信息

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-19
      • 2021-05-14
      • 2016-04-12
      • 2011-06-04
      • 2018-08-31
      • 2019-06-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多