Interface 为什么微服务之间的共享库不好?

Interface 为什么微服务之间的共享库不好?,interface,architecture,shared-libraries,microservices,distributed-computing,Interface,Architecture,Shared Libraries,Microservices,Distributed Computing,山姆·纽曼在他的书《建筑微服务》中写道 服务之间耦合过多的弊病远比代码重复所造成的问题更严重 我只是不明白服务之间的共享代码是如何邪恶的。作者的意思是,如果出现对共享库的需求,那么服务边界本身的设计就很糟糕,还是他真的意味着我应该在公共业务逻辑依赖的情况下复制代码?我看不出这能解决什么问题 假设我有两个服务共用的共享实体库。两个服务的公共域对象可能有味道,但另一个服务是调整这些实体状态的GUI,另一个是其他服务为其目的轮询状态的接口。相同的领域,不同的功能 现在,如果共享知识发生变化,我将不得不

山姆·纽曼在他的书《建筑微服务》中写道

服务之间耦合过多的弊病远比代码重复所造成的问题更严重

我只是不明白服务之间的共享代码是如何邪恶的。作者的意思是,如果出现对共享库的需求,那么服务边界本身的设计就很糟糕,还是他真的意味着我应该在公共业务逻辑依赖的情况下复制代码?我看不出这能解决什么问题

假设我有两个服务共用的共享实体库。两个服务的公共域对象可能有味道,但另一个服务是调整这些实体状态的GUI,另一个是其他服务为其目的轮询状态的接口。相同的领域,不同的功能

现在,如果共享知识发生变化,我将不得不重建和部署这两个服务,而不管公共代码是外部依赖项还是跨服务复制。通常,根据业务逻辑的同一条,相同的情况涉及两个服务的所有情况。在这种情况下,我只看到代码重复的危害,降低了系统的内聚性

当然,在共享库的情况下,偏离共享知识可能会引起头痛,但即使这样,也可以通过继承、组合和巧妙地使用抽象来解决

那么,Sam所说的代码复制比通过共享库进行过多耦合更好是什么意思呢

服务之间耦合过多的弊病远比代码重复所造成的问题更严重

作者在使用“耦合”这个通用词时非常不具体。我同意某些类型的耦合是严格禁止的(比如共享数据库或使用内部接口)。然而,公共库的使用并不是其中之一。例如,如果您使用golang开发两个微服务,那么您已经有了一个共享的依赖关系(对golang的基本库)。这同样适用于为共享目的而开发的库。请注意以下几点:

  • 对待共享的库就像对待第三方实体的依赖关系一样
  • 确保每个组件/库/服务具有不同的业务用途
  • 正确地对其进行版本设置,并将使用哪个版本的库留给相应的微服务团队来决定
  • 将开发和测试共享库的职责与微服务团队分开设置

别忘了,microservices的体系结构风格不是太注重代码组织或内部设计模式,而是更大的组织和流程相关方面,以允许扩展应用程序体系结构、组织和部署。请参阅以获取概述。

可以接受复制的紧密耦合的好例子可以是定义服务之间接口/DTO的共享库。特别是使用相同的类/结构来序列化/反序列化数据

假设您有两个服务—A和B—它们都可以接受稍有不同但总体上看起来几乎相同的JSON输入

让一个DTO来描述公共密钥是很有诱惑力的,也包括服务A和服务B作为共享库使用的极少数密钥

在一段时间内,系统运行良好。这两个服务都将共享库添加为依赖项,并正确构建和运行

不过,随着时间的推移,服务A需要一些额外的数据,这些数据将改变JSON的结构,而JSON的结构与以前相同。因此,您不能同时使用相同的类/结构来反序列化这两个服务的JSON-服务a需要更改,但服务B将无法反序列化数据

您必须更改共享库,将新功能添加到服务A并重建它,然后重建服务B以将其调整为共享库的新版本,即使其中的逻辑尚未更改

现在,您是否可以在内部为这两种服务分别定义DTO?从一开始,它们的契约就可以在您可以想象的任何方向上分别安全地发展。当然,一开始在这两种服务中保持几乎相同的DTO可能看起来有点难闻,但从长远来看,它给了您一个改变的自由

最终,(微)服务与monolith没有太大区别。关注点的分离和隔离至关重要。有些依赖项是无法避免的(语言、框架等),但在您自己引入任何其他依赖项之前,请仔细考虑未来的影响

我宁愿遵循给出的建议——复制DTO并避免共享代码,除非您无法避免。它曾经咬过我。上面的场景并不重要,但可能会更加微妙,影响更多的服务。不幸的是,它只是在一段时间后才会击中你,因此影响可能很大。

微服务体系结构的核心概念是,微服务有其独立的开发发布周期。“共享库”破坏了这一点

更长

根据我自己的经验,尽可能保持微服务的独立性是非常重要的。隔离基本上是指能够在大多数情况下独立于任何其他服务发布和部署服务。 换句话说,它有点像:

  • 您构建了服务的新版本
  • 您(在测试之后)发布它
  • 您可以将其部署到生产环境中
  • 您没有导致整个环境的部署级联
“共享库”在我的定义中,这些库确实会妨碍您这样做


“共享库”如何毒害您的体系结构是“有趣的”:

哦,我们有一个用户obje