消耗Kafka主题后发送HTTP响应

时间:2019-02-04 23:41:51

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

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

但是,我有几个问题不确定如何从概念上解决。 我正在使用API​​网关服务作为应用程序的主要条目。它充当将操作转发到适用的微服务的主要代理。 请考虑以下情形:

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

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

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

谢谢。

2 个答案:

答案 0 :(得分:1)

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

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

  2. 一旦有了订单ID,就以原子方式(全有或全无)在Kafka主题上写一条事件消息。成功完成此操作后,您可以将成功响应发送回客户端。在此阶段不要写多个主题,因为写多个主题会失去原子性。您总是可以有多个将事件写入其他多个主题的使用者组。一个消费者组应将数据写入某个持久性数据库中以进行查询

  3. 现在,您需要解决读自己写的问题,即在收到成功响应后,用户希望立即查看订单。但是您的数据库可能尚未使用订单数据进行更新。为此,请将订单数据写入Kafka之后并返回成功响应之前,立即将订单数据写入Redis或Memcached之类的分布式缓存中。当用户读取订单时,将返回缓存的数据

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

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

  6. 最后,如果要确保为订单保留订购的商品,以便其他人都不能拿走,例如预订飞机座位或一本书的最后一本,则需要一种共识算法。您可以为此使用Apache Zookeeper,并在该项目上创建分布式锁

答案 1 :(得分:0)

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

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

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