在我新工作的项目中,我发现微服务不会直接从一个微服务向另一个微服务发出post / put API调用,而是会向kafka生成一条消息,然后由单个微服务使用。
例如,“订单”微服务会将记录发布到“待定订单”主题,然后由“库存”微服务(没有其他使用者)使用。反过来,在使用记录并进行了一些处理之后,库存微服务将产生一条记录为“已处理订单”,然后该记录仅由订单微服务使用。
这是正确的用例吗?还是在这种情况下仅在微服务之间进行API调用会更好?
答案 0 :(得分:0)
在基于微服务的应用程序中,Kafka有两个强大的用例:
作为单个最终用户活动的一部分,您需要在多个微服务中进行状态更改。如果通过依次或并行调用所有适当的微服务API来执行此操作,将出现两个问题: 首先,您失去原子性,即无法保证“全有或全无”。对微服务A的调用很可能会成功,但对服务B的调用会失败,这将导致永久的数据不一致。其次,在云环境中,不可预知的延迟和网络超时并不少见,因此当您将多个呼叫作为单个呼叫的一部分时,这些呼叫之一被延迟或失败的可能性会极大地影响用户体验。因此,这里的一般建议是,您将Kafka主题中的用户操作原子地写为一个事件,并具有多个使用者组-每个感兴趣的微服务都使用一个使用者组来消耗事件并在其自己的数据库中进行状态更改。如果操作是由用户从UI触发的,则您还需要提供“自己读写”保证,即用户希望在写完后立即查看其数据。因此,您需要首先在第一个微服务的本地数据库中写入事件,然后基于日志的event sourcing(使用aporopriate Kafka Connector)将事件数据传输到Kafka。这将使您能够从本地数据库向用户显示数据。您可能还需要更新缓存,搜索索引,分布式文件系统等,所有这些都可以通过使用各个微服务发布的Kafka事件来完成。
您需要从多个微服务中提取数据以执行某些活动或聚合数据并显示给用户,这并不少见。通常,由于上述延迟和超时问题,因此不建议这样做。通常建议我们根据其他微服务更改状态时发布的Kafka事件,在微服务本地数据库中预先计算这些聚合。这将使您更快地将聚合数据提供给用户。这称为materialized view模式。
这里唯一要记住的一点是写Kafka日志或代理,并以异步方式从其中读取,可能会有一些时间延迟。
答案 1 :(得分:-1)
微服务作为消费者,对我来说似乎是可疑的。您可能是说该主题的侦听器会使用该消息,并且可能会调用您的第二个微服务,即库存微服务。
是的,该模型很好,特别是当您想要异步行为和通过它处理的流量负载时。
想象一个场景,当您有多个要从1个端点调用的微服务。在这里,您需要要么聚合服务的聚合层,然后调用它一次,要么您想要向Kafka发布几条消息,然后该任务就可以完成。
还要考虑读取服务,如果您需要调用微服务从其他地方读取一些数据,那么您将无法使用Kafka。
这完全取决于您的要求和设计。