微服务:共享库与代码复制

时间:2018-06-26 10:37:23

标签: .net asp.net-core architecture microservices

类似的问题被问了几次,但是由于每个用例都可能不同,所以我认为有必要针对我所面对的特定情况再次提出该问题。 因此,我们正在使用.netCore开发微服务。我们将这些服务称为 ServiceA ServiceB ServiceC

常见实体

如果 ServiceA 调用 ServiceC ,则 ServiceC 使用JSON内容进行响应,该内容可以序列化为 ResponseC 对象

这意味着 ServiceA ServiceC 应该都知道 ResponseC 类。 在这一点上,我看到两种可能性。 ResponseC 类可以位于共享库中,并且 ServiceA ServiceC 都应对此共享库进行引用。 但是,我阅读了诸如不在微服务之间共享库之类的语句。这导致了另一种可能的解决方案。让我们在两个微服务中都引入 ResponseC 类,但是由于代码重复,我不知何故觉得这有点不利于可维护性。

通用逻辑

ServiceA ServiceB ServiceC 通信。与 ServiceC 通信时,我们打算制定一些有关读取和连接超时以及最大重试次数的策略。这些值是可配置的,并且重试逻辑中还包含一些公共部分,以便能够从配置文件中读取相关值并包装http调用。 问题与前面的案例几乎相同,因为我要么将这些类放入共享库中,要么基本上在 ServiceA ServiceB 中引入了相同的类。这些类非常简单且通用,因此目前我无法想象,这些类会经常更改。

问题是,在这些情况下,重复代码并拥有独立的微服务或引入使这些服务依赖的共享库,哪个更好?

3 个答案:

答案 0 :(得分:3)

关于模型类,我说重复的代码。使用JSON或某种其他语言独立协议而不是序列化的本机Java对象(例如)的整个想法是为了避免整个微生态系统中的一个微服务波纹中类更改的副作用。共享的模型类库将多个微服务锁定为一夫多妻制的婚姻合同,在该合同中,一对成员之间即使很小的分歧也可能导致离婚。服务A可能需要更改其模型,这不仅是服务B不需要的,而且可能与它完全不兼容。

这并不意味着不能在不同的微服务之间共享代码。在不同的微服务之间共享库没有什么错,只要它们的功能仅限于解决跨领域的问题即可。也许您提到的常见超时和重试功能属于此类别。在我看来,除了保留语言独立协议的数据表示之外什么也不做的模型类不属于此类。

答案 1 :(得分:2)

当然,编程中有DRY规则。但是,正如萨姆·纽曼(Sam Newman)在他的《构建微服务》一书中所说:不要在一个微服务中重复自己。

公共实体: 让我们用 ResponseC 看一下您的示例。想象一下, ServiceB 中的某些内容已发生更改,因此响应中的字段之一已更改-现在您必须更新使用此共享库的每个服务,即使该服务没有需要这个改变的领域。如果您对每个服务都具有 ResponseA ResponseB ResponseC ,则不必使用新的依赖项来更新每个服务。

常见逻辑: 基本上,这里应用相同的规则。但是,通常使用一些第三方库来解决常见的微服务问题,例如超时和重试。我还可以建议看一下service meshistio之类的linkerd实现。服务网格将这些问题的可能性提供给基础结构层,因此您可以专注于编写业务逻辑。

答案 2 :(得分:1)

我同意上面的意见,而不希望复制类代码。我在通过内部NuGet服务器分发共享类的过程中走了个路,但效果不佳。 JSON的不同微服务使用者使用NuGet类开始,但很快就要求进行更改以破坏其他更改。最终,所有消费者都忽略了NuGet类,并创建了自己的类。