在微服务之间共享代码和模式

如果你在你的组织中使用微服务架构 ,他们可以通过zookeeper或者它的等价物来共享configuration。 但是,各种服务应该如何共享一个共同的数据库模式? 常见的常量? 和普通公用事业?

一种方法是将所有的微服务放在同一个代码库中,但这与微服务的解耦是矛盾的。

另一种方法是让每个微服务都是完全独立的,但是这将导致每个微服务必须拥有的独立数据库中的代码重复和数据重复。

还有一种方法是实现没有上下文状态的function微服务,但这通常是不现实的,会推动架构有一个中心枢纽,维护上下文\状态以及来自\的大量stream量。

在微服务之间共享代码和模式将是一个可扩展的,高效的,实用的,希望是美丽的方式?

关于通用代码,使用包装系统的最佳实践。 所以,如果你使用Java,那么使用maven,如果你使用Ruby然后Gems,如果python,然后pypi等。理想情况下,包装系统增加了很小的摩擦力,所以你可能有一个(比如,git)用于不同主题的库),并通过工件库(例如private maven / gems / pypi)发布它们的工件。 然后在微服务中添加对所需库的依赖。因此,重用代码非常简单。 在某些情况下,包装系统会增加一些摩擦(maven for one),所以人们可能更喜欢使用单一的git回购(git repo)来处理所有事情,并且可以使用多模块项目设置。 这并不像第一种方法那么干净,但是也可以运行,并不是太糟糕。 其他选项是使用git子模块(不太需要)或git子树(更好),以便将源代码包含在单个“父”存储库中。

关于模式 – 如果你想按照本书玩,那么每个微服务都有自己的数据库。 他们不接触彼此的数据。 这是一个非常模块化的方法,起初似乎给你的过程增加了一些摩擦,但最终我想你会感谢我。 它将允许对微服务进行快速迭代,例如,您可能希望用一个特定服务的另一个数据库实现replace一个数据库实现。 想象一下,当所有的服务使用相同的数据库时,这样做! 祝你好运…但是,如果每个单一的服务使用它自己的数据库服务抽象数据库正确(例如,它不接受SQL查询作为API调用,例如;-))然后改变到Cassandra的MySQL突然变得可行。 完全隔离的数据库还有其他的好处,例如负载和扩展,发现瓶颈,pipe理等。

所以简而言之 – 通用代码(实用程序,常量等) – 使用一个打包系统或一些源代码链接,比如git-tree

数据库 – 你不碰我的,我不碰你的。 这是更好的方法。

HTH,Ran。

“最纯粹”的方法,即给你最less量的耦合,是不共享任何代码

如果您发现两个服务(称为A和B)需要相同的function,您的select是:

  • 拆分如果作为单独的服务C,所以A和B可以使用C
  • 咬住子弹并复制代码

虽然这可能听起来很尴尬,但是你避免了创造一个人人都依赖的“实用工具”,“共同的”或“基础设施”库的问题(并不less见),那么真正难以升级和改变(即间接耦合服务)。

在实践中,像往常一样,这是一个折衷。

  • 如果共享的function是实质性的,我会去一个单独的服务。
  • 如果只是常量,共享库可能是最好的解决scheme。 不过,您需要非常小心向后兼容性。
  • 对于configuration数据,您也可以实现一个特定的服务,可能使用一些现有的技术,如LDAP。
  • 最后,对于可能独立演变的简单代码,只需复制可能是最好的解决scheme。

但是,什么是最好的取决于你的具体情况和问题。

从我的项目经验

在使用SOAP时共享WSDL(不是服务模型代码,因为它们应该从WSDL生成)。 在使用REST时,为客户端和服务器设置不同的模型(复制yes但不共享)。 第二名或第三名消费者一进场,你就会惹上麻烦。 保持它们的分离。 一个服务的操作和使用在数据结构上比以往更加频繁。 另一个客户想要使用你的服务,或者第二个版本必须同时运行。

一些额外的想法

共享与可扩展性是部分矛盾的。 无分享和分享一些/分享都有优点和缺点。 无需分享,随时为您提供充分的灵活性。 微服务是提供特定域服务的独立组件。

共享业务域数据模型是一种常见的模式( http://www.ivarjacobson.com/resources/resources/books/#object%20oriented%20software ),可防止重复。 由于微服务划分和征服业务部分,可能难以共享业务领域数据模型的某些内容。

微服务彼此通信,所以我理解共享这些通信数据模型(主要是基于HTTP)的需要。 如果您在服务提供商和消费者之间有一对一的映射,那么共享这些数据模型可能是可以的。 只要你有多个消费者在一个模型内需要不同型号/领域的服务,就会变得艰难。

对于ISP原则(接口分割原则),客户端应该依赖于接口而不是实现。我会build议如果可以通过这种方式共享接口而不是实现,那么最好使系统与实现分离。