Microservices 是否有一个“问题”;“最佳做法”;在微服务开发中对数据库表进行版本控制?

Microservices 是否有一个“问题”;“最佳做法”;在微服务开发中对数据库表进行版本控制?,microservices,versioning,database-table,Microservices,Versioning,Database Table,正在使用微服务实现一个系统。为了减少体系结构中“在同一级别”实现的微服务之间的交互,一些微服务将本地缓存由其他服务管理的表的副本。假设本地缓存的表(a)经常被微服务以“读取模式”访问,并且(b)具有相对静态的内容(即,更多的是“查找表”而不是事务性内容) 本地缓存将使用服务间消息传递来保持同步。由于内容应该是相当静态的,因此这不应该是一个重大问题/工作量。但是,在启动微服务时,本地缓存可能已过时 我想在源表上实现某种滚动版本号,这样具有本地缓存的微服务可以检查此版本号,以潜在地避免重新同步事件

正在使用微服务实现一个系统。为了减少体系结构中“在同一级别”实现的微服务之间的交互,一些微服务将本地缓存由其他服务管理的表的副本。假设本地缓存的表(a)经常被微服务以“读取模式”访问,并且(b)具有相对静态的内容(即,更多的是“查找表”而不是事务性内容)

本地缓存将使用服务间消息传递来保持同步。由于内容应该是相当静态的,因此这不应该是一个重大问题/工作量。但是,在启动微服务时,本地缓存可能已过时

我想在源表上实现某种滚动版本号,这样具有本地缓存的微服务可以检查此版本号,以潜在地避免重新同步事件


这种方法是否有“最佳实践”?或者,考虑到每个微服务都有自己的数据库(即没有共享数据库)支持,这是一个“更好的选择”

在我看来,您不应该在启动时加载数据。维护版本可能有点复杂

缓存旁模式

一般来说,在微服务体系结构中,你考虑“缓存旁路模式”。您不在前端构建缓存,而是按需构建缓存。当您收到一个请求时,您检查缓存,如果它不在那里,您用最新的值更新缓存并返回响应,从那里它总是从缓存返回。这样做的好处是,您不需要在前端加载所有内容。假设您有200条记录,而服务只经常使用其中的50条,您正在维护可能不需要的额外缓存

让请求构建缓存,这是一次DB命中。您可以在缓存上设置过期时间,并重新生成传入请求

如果您的数据是完全静态的(永远不会更改),那么这个模式可能不值得讨论,但是如果您有一个每周、每月都可以更改一次的查找表,那么您应该使用缓存过期时间更长的模式。维护该版本可能会花费高昂的成本。但真正取决于您可能想要如何实现


我们遇到了同样的问题,并通过使用
LastUpdated
时间戳比较(与您的版本号相同的概念)暂时解决了这个问题。每天晚上(当我们的应用程序运行缓慢时),每个服务都会发布一条
serviceslastupdated
消息,其中包括添加/编辑其拥有的数据时的最新时间戳。订阅此数据的任何其他服务都会处理该消息,如果存在不匹配,它会请求自上次本地更新以来“接触”的所有行,以便恢复同步

对于我们来说,目前来说,这是可以接受的,因为新服务不会在同一天上线并投入使用。但是,我们未来的计划是,任何时候服务启动时,它都可以为每个订阅的服务发布一条消息,指示其最近的缓存更新时间戳。如果“源”服务发现时间戳不是最新的,它可以发送更新以重新同步数据。这样做的好处是,即使(至少对我们来说)订阅的所有服务都可以访问消息,也只向需要更新的特定服务发送所需的更新

我们从使用持久队列开始,这样,如果一个微服务的所有实例都关闭了,消息就会在它的队列中累积。有两个问题促使我们构建更好的产品:

1) 显然,这并不能解决“首次启动”的情况,因为没有消息队列

2) 如果在存储排队的消息或处理它们时出现任何错误,您最终会失去同步。如果发生这种情况,你仍然需要一个像我们现在这样的主动机制来恢复同步。所以,走这条路似乎是值得的


我不会说我们的方法是“最佳实践”,如果有,我也不知道。但是,到目前为止,我们的做法(包括计划中的未来工作)已被证明是易于构建、易于理解和监控的,并且非常可靠,因为我们很少会收到由本地数据不同步引起的事件。

我不认为将缓存放在一边对此有用,因为不保证本地缓存的行与源同步。此外,本地缓存还需要满足来自其他表、微服务本地表和微服务控制表的引用。因此,实际上,启动时微服务需要本地缓存中的所有行(即,本地缓存的内容不受微服务上的请求驱动)。但是,感谢您指出缓存搁置模式。这是一篇有趣的文章,我喜欢基于时间戳的比较,因为这可以最大限度地减少重新同步表所需的行数。我目前倾向于让订阅者在启动时询问当前版本,但让提供商在启动时发送消息似乎也不是一个坏主意(即,两者都做)。好奇……你如何处理“删除”?@SoCal我们在记录上使用一个标志来指示其状态。因此,“delete”本质上只是对行的修改。编辑添加:这取决于接收服务如何处理删除,没有理由在该标志更改时无法实际删除行。但是,在任何当前用例中,我们实际上都不会删除它们。