【问题标题】:How to design a database idempotent microservice (POST)如何设计数据库幂等微服务(POST)
【发布时间】:2018-02-27 16:56:18
【问题描述】:

这是一个关于如何设计 POST 数据库服务(实现微服务的新手)的非常普遍和基本的问题。假设您有一个 SaveCustomer 微服务。您需要一个 POST 来传递客户数据,SaveCustomer 服务接收数据 (JSON) 并将其插入到数据库中。

由于网络拥塞等原因,客户端可能会重试并发送重复请求,那么如何确保不会在数据库中插入重复记录?

谢谢 奥贝德

【问题讨论】:

  • POST 不应该是 idempotent
  • 好的,那么我应该如何实现将记录插入数据库的服务?任何建议,因为我是微服务新手

标签: rest http-post microservices


【解决方案1】:

虽然 POST 不是幂等的,但您可以通过为每个命令分配一个唯一的 ID(例如 GUID)来实现这一点。然后,在微服务上,在执行命令之前,检查该命令是否尚未处理。如果是,则忽略它,否则将其发送到执行实际更新的实际组件并将命令标记为已执行。

这个解决方案很优雅,因为它可以作为一个附加组件实现,可以装饰核心逻辑,跟在Open/close principleSingle responsibility principle 之后。此外,您可以使用Dependency injection root configuration 来使用或不使用这种等效性保护。

【讨论】:

  • 感谢您的回复,是否有任何资源/示例/教程可以显示人们通常如何实施此类服务(插入数据库记录的休息服务),展示如何实施此类服务以及如何调用此服务来自另一个服务(意味着处理重试等)。
  • 我的场景:我有一个微服务必须在处理后插入一条记录,但是我不希望用户/客户端遇到任何延迟(如果数据库不堪重负,有时可能会出现这种情况)在调用此服务时。因此,我正在考虑使插入异步,即将插入语句发送到队列(Kafka)并通过消费者客户端处理它们。这种方法是一个好的解决方案吗?有没有其他的解决方案,我不会丢失数据,也不会因为数据库性能问题而降低用户体验?
  • @obaid 使用命令队列是一种解决方案。其他解决方案可能是使用事件驱动架构。因此,您的客户端服务应该发布一个事件。然后 Saga/Process 管理器应该获取(通过订阅或轮询)该事件并向下一个微服务发出命令,如果出现问题则重试。这种架构更好,但也意味着大重构,因为您的微服务应该按域/子域拆分。您应该看看 DDD 方法(域驱动设计),它通过有界上下文拆分单体。
猜你喜欢
  • 2016-12-13
  • 2021-11-17
  • 1970-01-01
  • 2019-08-11
  • 2019-10-08
  • 2017-09-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多