【问题标题】:Sending HTTP response after consuming a Kafka topic消费 Kafka 主题后发送 HTTP 响应
【发布时间】:2019-06-28 18:31:47
【问题描述】:

我目前正在编写一个包含大量微服务的 Web 应用程序。我目前正在探索如何在所有这些服务之间进行正确的通信,并且我决定坚持使用消息总线,或者更具体地说是 Apache Kafka。

但是,我有几个问题不知道如何从概念上解决。 我使用 API 网关服务作为应用程序的主要入口。它充当将操作转发到适用的微服务的主要代理。 考虑以下场景:

  1. 用户向 API 网关发送 POST 请求,其中包含一些信息。
  2. 网关生成新消息并将其发布到 Kafka 主题。
  3. 订阅的微服务获取主题中的消息并处理数据。

那么,我现在应该如何从网关响应客户端?如果我需要来自该微服务的一些数据怎么办?感觉 HTTP 请求可能会超时。我应该在客户端和 API 网关之间坚持使用 websocket 吗?

另外,如果客户端发送一个 GET 请求来获取一些数据,我应该如何使用 Kafka 来解决这个问题?

谢谢。

【问题讨论】:

    标签: javascript node.js apache-kafka microservices backend


    【解决方案1】:

    假设您要创建一个订单。它应该是这样工作的:

    1. 传统上,我们在 RDBMS 表中使用自增字段或序列来创建订单 ID。但是,这意味着在我们将订单保存到数据库之前不会生成订单 ID。现在,在 Kafka 中写入数据时,我们不会立即写入数据库,并且 Kafka 无法生成订单 ID。因此,您需要使用一些可扩展的 id 生成实用程序,例如 Twitter Snowflake 或具有类似架构的工具,以便您甚至可以在 Kafka 中编写订单之前生成订单 id

    2. 获得订单 ID 后,以原子方式(全有或全无)在 Kafka 主题上编写单个事件消息。成功完成后,您可以向客户端发送回成功响应。在这个阶段不要写多个主题,因为你会因为写多个主题而失去原子性。您始终可以有多个消费者组将事件写入多个其他主题。一个消费者组应该将数据写入某个持久数据库中以进行查询

    3. 您现在需要解决 read-your-own-write 问题,即在收到成功响应后,用户希望立即查看订单。但是您的数据库可能尚未使用订单数据进行更新。为了实现这一点,在将订单数据写入 Kafka 并返回成功响应之前,立即将订单数据写入 Redis 或 Memcached 等分布式缓存。用户读取订单时,返回缓存数据

    4. 现在您需要使用最新的订单状态更新缓存。您始终可以让 Kafka 消费者从 Kafka 主题中读取订单状态

    5. 确保您不需要将所有订单保存在高速缓存中。您可以基于 LRU 驱逐数据。如果在读取订单时,数据不在缓存中,则会从数据库中读取并写入缓存以供将来请求

    6. 最后,如果你想确保订购的物品是为订单保留的,这样其他人就不能拿走,比如预订飞机座位,或者最后一本书,你需要一个共识算法。您可以为此使用 Apache Zookeeper 并在项目上创建分布式锁

    【讨论】:

      【解决方案2】:

      您可以选择在网关中创建更多端点吗?

      我会让 POST 端点专门用于将消息生成到 Kafka 队列,其他微服务将使用该队列。作为从端点返回的对象,它将包含某种引用或 id 来获取消息的状态。

      并在网关中创建另一个 GET 端点,您可以在其中使用创建时获得的消息的引用来检索消息的状态。

      【讨论】:

      • 当然,这是可能的。但是我应该如何在 Kafka 中实现检索功能呢?因为我需要从微服务中获取数据。对不起,如果我有点脱离循环:)
      • @emilwidlund 在项目中,我们与消费者有单独的微服务,它从名为“PROCESSED MESSAGES”的特殊主题中获取数据,更新数据库中的消息状态并通过 WebHooks 通知系统客户
      猜你喜欢
      • 2023-02-02
      • 2017-11-24
      • 1970-01-01
      • 1970-01-01
      • 2020-11-27
      • 2017-10-17
      • 2014-03-28
      • 2021-07-28
      • 1970-01-01
      相关资源
      最近更新 更多