3

我工作的公司正在研究从我们当前的单体 API 迁移到微服务。我们当前的 API 严重依赖于 Spring,我们使用 SQL Server 来实现大部分持久性。我们的微服务调查倾向于 spring-cloud、spring-cloud-stream、kafka 和 polyglot 持久性(每个微服务的隔离数据库)。

我有一个关于通过 kafka 进行消息传递通常如何在微服务架构中完成的问题。我们计划在一组微服务和我们的客户端应用程序之间建立一个协调层,该层将协调不同微服务之间的活动,并将客户端与微服务 API 的更改隔离开来。我们读过的关于使用 spring-cloud-stream 和 kafka 的大部分内容都表明我们应该在协调层(源)使用流来进行资源更改操作(插入、更新、删除),而微服务是消息。

我遇到问题的地方是插入。我们大量使用数据库分配的标识符(身份列/自动增量列/序列/代理键),它们通常作为发布请求的一部分分配并返回给调用者。协调层可能会使用不同的微服务保存多个内容,并且通常需要从一个插入中分配的标识符才能继续进行下一个操作。使用协调层和微服务之间的消息进行插入使得协调层无法从插入操作中获得响应,因此无法获得所需的分配标识符。此外,流上的其他消费者(即,将数据发布到数据仓库的消费者)确实需要消息包含分配的标识符。

人们如何处理这个问题?数据库分配的标识符是微服务中的反模式吗?我们是否应该公开返回数据库分配标识符的单独微服务端点,以便协调层可以在调用异步插入之前进行同步调用以获取标识符?我们可以使用 UUID,但我们的 DBA 讨厌将它们用作主键,并且它们不能用作订单号或其他面向用户的生成 id。

4

2 回答 2

1

如果您可以在从消息源接收时更早地以编程方式创建标识符,则可以将标识符作为消息头的一部分嵌入,然后在数据库插入期间和任何其他使用者中使用消息头信息。

但是这种方法需要其他消费者针对数据库单独验证以仅处理已提交的事务(如果您关心仅处理插入)。

于 2016-04-15T04:57:35.170 回答
-1

在我们公司,我们建立了一个专门负责生成唯一 ID 的服务。并且所有其他服务都从那里获取他们需要的 ID。

这些生成的 id 不能用作订单号,但我认为无论如何都不应该将其用于这项工作。如果您需要按创建日期排序,最好有一个 created_date 字段。

用这种方法困扰我的另一件事是,主要资源可能会在通过 id 重新引用它的其他资源之后持久化。例如,插入用户和插入用户地址请求负载是异步发送的。插入用户有效负载包含生成的唯一 id,用户地址有效负载包含该 id 作为外部引用返回给用户。插入用户地址可能在插入用户请求之前处理,但完全没问题。我认为这叫做最终一致性。

于 2016-04-17T09:14:17.250 回答