我现在正在写一个web应用程序,它有很多微服务。我目前正在探索如何在所有这些服务之间正确地通信,我决定坚持使用消息总线,或者更具体地说是apachekafka。
然而,我有几个问题,我不知道如何在概念上绕过。我使用api网关服务作为应用程序的主要入口。它充当主代理,将操作转发到适用的微服务。考虑以下场景:
用户向api网关发送一个post请求,其中包含一些信息。
网关生成新消息并将其发布到Kafka主题。
订阅的微服务接收主题中的消息并处理数据。
那么,我现在应该如何从网关响应客户端呢?如果我需要微服务的数据怎么办?感觉http请求可能会超时。我应该在客户端和api网关之间使用websockets吗?
而且,如果客户机发送get请求来获取一些数据,那么我应该如何使用kafka来实现这一点?
谢谢。
2条答案
按热度按时间bfrts1fy1#
您有在网关中创建更多端点的选项吗?
我会让post端点专门用于向kafka队列生成消息,其他微服务将使用该队列。作为从端点返回的对象,它将包含某种引用或id来获取消息的状态。
并在网关中创建另一个get端点,从中可以检索消息的状态以及创建消息时获得的消息的引用。
lhcgjxsq2#
假设你要创建一个订单。这就是它的工作原理:
传统上,我们在rdbms表中有一个自动递增的字段或序列来创建订单id。但是,这意味着在我们将订单保存到db中之前,不会生成订单id。现在,在kafka中写入数据时,我们不会立即写入db,kafka无法生成订单id。因此,您需要使用一些可伸缩的id生成工具,如twitter snowflake或具有类似架构的东西,以便您甚至可以在kafka中写入订单之前生成订单id
一旦你有了订单id,就在kafka主题上原子地写一个事件消息(要么全有要么全无)。一旦成功完成,您就可以向客户机发回一个成功响应。在这个阶段不要写多个主题,因为你会因为写多个主题而失去原子性。始终可以有多个使用者组将事件写入多个其他主题。一个使用者组应该将数据写入某个持久性数据库以进行查询
您现在需要解决read-your-own-write问题,即在收到成功响应后,用户将立即希望看到订单。但是您的数据库可能还没有更新订单数据。要实现这一点,请在将订单数据写入kafka之后并在返回成功响应之前立即将订单数据写入redis或memcached之类的分布式缓存。当用户读取订单时,将返回缓存的数据
现在您需要用最新的订单状态更新缓存。你可以让Kafka消费者从Kafka主题中读取订单状态
以确保不需要在缓存内存中保留所有订单。您可以基于lru逐出数据。如果在读取订单时,数据不在缓存中,则会从数据库中读取数据并写入缓存以备将来的请求
最后,如果您希望确保为订单保留已订购的项目,以便其他人无法购买,例如预订航班座位或最后一本书,则需要一个一致算法。您可以使用apachezookeeper来实现这一点,并在该项上创建一个distributed锁