我所工作的公司正在研究从目前的单片API转向微服务。我们当前的API严重依赖于spring,我们使用SQL服务器来实现大多数持久性。我们的微服务调查倾向于春云,春云流,卡夫卡和多语言持久性(每个微服务的孤立数据库)。
我有一个问题,关于如何通过kafka进行消息传递通常是在微服务架构中完成的。我们计划在微服务集和客户端应用程序之间建立一个协调层,它将协调不同微服务之间的活动,并将客户端与微服务API的更改隔离开来。我们读到的关于使用spring-cloud-stream和kafka的大多数内容表明我们应该在协调层(源)使用流来进行资源更改操作(插入,更新,删除),微服务是一个消费者。消息。
我遇到麻烦的地方是插入。我们大量使用数据库分配的标识符(标识列/自动递增列/序列/代理键),它们通常被指定为发布请求的一部分并返回给调用者。协调层可以使用不同的微服务来保存多个内容,并且在它可以继续进行下一个操作之前通常需要来自一个插入的分配的标识符。在协调层和微服务之间使用消息传递进行插入使得协调层无法从插入操作获得响应,因此无法获得所需的已分配标识符。此外,流上的其他消费者(即将数据发布到数据仓库的消费者)确实需要消息来包含分配的标识符。
人们如何处理这个问题?数据库分配的标识符是微服务中的反模式吗?我们是否应该公开单独的微服务端点,这些端点返回数据库分配的标识符,以便协调层可以在调用异步插入之前进行同步调用以获取标识符?我们可以使用UUID,但我们的DBA讨厌那些主键,它们不能用作订单号或其他面向用户的生成ID。
答案 0 :(得分:1)
如果您可以在从消息源接收时以编程方式创建标识符,则可以将标识符作为消息标题的一部分嵌入,然后在数据库插入期间和任何其他使用者中使用消息标头信息。
但是这种方法需要其他消费者对数据库进行单独验证,以便仅处理已提交的事务(如果您只关心处理插入事件)。
答案 1 :(得分:-1)
在我们公司,我们建立了一个专门的服务,负责独特的ID生成。其他所有服务都会从那里获得他们需要的ID。
这些生成的ID不能用作订单号,但我认为不应该将它用于此作业。如果您需要按创建日期排序,最好有一个created_date字段。
用这种方法让我误解的另一件事是,主要资源可能会在另一个用id重新引用它的资源之后保留。例如,插入用户和插入用户地址请求有效负载是异步发送的。插入用户有效负载包含生成的唯一ID,用户地址有效负载包含该id作为外部引用返回给用户。插入用户地址可能在插入用户请求之前被占用,但它完全没问题。我认为它被称为最终的一致性。