如果您在组织中使用微服务架构,他们可以通过zookeeper或其等价物共享配置。但是,各种服务应该如何共享公共数据库模式?常见的常数?和普通的公用事业?
一种方法是将所有微服务放在同一个代码库中,但这与微服务带来的解耦相矛盾......
另一种方法是让每个微服务完全独立,但这会导致每个微服务必须保留的单独数据库中的代码重复和数据重复。
另一种方法是实现没有上下文\状态的功能微服务,但这通常是不现实的,并且会推动架构有一个中央集线器来维护上下文\状态和来自\的大量流量。 / p>
在微服务之间共享代码和架构的可扩展,高效,实用且有希望的方式是什么?
答案 0 :(得分:31)
关于通用代码,使用包装系统的最佳做法。所以如果你使用Java,那么使用maven,如果你使用Ruby然后使用Gems,如果使用python然后使用pypi等。 理想情况下,打包系统几乎没有摩擦,因此您可能拥有一个(例如,git)存储库用于公共库(或几个不同主题的公共库),并通过工件存储库(例如私有maven / gems / pypi)发布其工件。然后在微服务中添加对所需libs的依赖。因此代码重用很容易。 在某些情况下,包装系统会增加一些摩擦力(maven为一个),因此人们可能更喜欢使用单个git repo来处理所有事情和多模块项目设置。这不像第一种方法那样干净,但效果也不错。 其他选项是使用git子模块(不太需要)或git子树(更好),以便将源代码包含在单个"父级"库中。
关于模式 - 如果你想阅读本书,那么每个微服务都有自己的数据库。他们不会互相触碰对方的数据。这是一种非常模块化的方法,起初似乎会给你的过程带来一些摩擦,但最终我觉得你会感谢我。它允许快速迭代您的微服务,例如,您可能希望将一个数据库实现替换为一个特定服务的另一个数据库实现。想象一下,当所有服务使用相同的数据库时,这样做!好运...但是如果每个单独的服务都使用它自己的数据库,那么服务正确地抽象数据库(例如,它不接受SQL查询作为API调用,例如;-))然后将mysql更改为Cassandra突然变为可行。 拥有完全孤立的数据库还有其他优势,例如负载和扩展,发现瓶颈,管理等。
简而言之 - 公共代码(实用程序,常量等) - 使用打包系统或某些源代码链接,例如git-tree
数据库 - 你不碰我的,我不碰你的。这是解决这个问题的更好方法。
HTH,Ran。
答案 1 :(得分:14)
“最纯粹”的方法,即提供最少量耦合的方法,是不共享任何代码。
如果您发现两项服务(称为A和B)需要相同的功能,您的选项是:
虽然这可能听起来很尴尬,但您可以避免创建“实用程序”或“常用”或“基础架构”库(每个人都依赖它)的问题(并非罕见),然而这个库很难升级和更改(即间接地联合服务)。
在实践中,像往常一样,这是一种权衡。
然而,最好的将取决于您的具体情况和问题。
答案 2 :(得分:4)
从我的项目经验
使用SOAP时共享WSDL(不是服务模型代码,因为它们应该从WSDL生成)。使用REST时,为客户端和服务器设置不同的模型(复制是但不共享)。一旦第二个或第三个消费者发挥作用,你就会遇到麻烦。让他们脱钩。在过去,服务的操作和使用比数据结构更改。另一个客户希望使用您的服务,或者必须同时运行第二个版本。
一些额外的想法
共享与可伸缩性部分矛盾。无共享和共享 - 共享/共享 - 都有利弊。什么都不共享,随时为您提供充分的灵活性。微服务是提供特定域服务的独立组件。
共享业务域数据模型是一种常见模式(http://www.ivarjacobson.com/resources/resources/books/#object%20oriented%20software),可防止重复。由于微服务可以分割和征服业务部分,因此可能很难分享业务领域数据模型。
微服务相互通信,因此我理解共享这些通信数据模型(主要是基于HTTP)的需要。如果您在服务提供商和消费者之间进行一对一映射,则可以共享这些数据模型。一旦你有一个服务的多个消费者需要在模型中使用不同的模型/字段,那就很难了。
答案 3 :(得分:0)
关于ISP原则(接口分割原则)客户端应该依赖于接口而不是实现。我建议如果可能通过这种方式共享接口而不是实现,那么最好使系统与实现分离。