确定微服务的范围

诚然,如果每个微服务都有单一职责,这个问题就不会那么普遍。然而,定义单一职责的范围并不容易。

为了便于讨论,让我们考虑一个支付服务,其职责是在电子商务平台上接受付款。假设最初只有两种支付方式:卡和优惠券,并且这两种方式都在同一个服务中实现。这可以吗?“接受付款”是单一责任还是我们应该为每种付款方式创建不同的服务?为什么停在那里?为什么不为每种类型的卡创建不同的服务:Visa、Mastercard、American Express 等?

了解一些未来的要求有助于做出更明智的决定,但通常这是我们所没有的奢侈。因此,让我们想象一下,根据当前可用的信息,我们决定使用单一服务负责付款。

不断变化的需求

几周后,接受 Paypal 和 Apple Pay 付款的新要求将会出台。现在感觉在现有服务中实施这些新的支付方式将使服务变得太大并且承担“太多责任”。鉴于这些新要求,决定根据支付方式将支付责任划分为不同的服务。

Paypal和Apple Pay的支付将在单独的服务中实现,但是实现两种不同支付方式的现有服务该怎么办?鉴于现在责任是在支付方式层面定义的,原来的支付服务与这种新方法不一致。因此,该服务需要拆分为两个新服务。

在单体应用程序中,上述更改相当于相对简单的代码重构,而在微服务架构中,代码将移动到新服务中,通常需要:新的代码存储库、新的持续集成/交付管道、环境配置、云计算/存储资源等

微服务命名

随着服务范围的变化,甚至名称也会过时。在我们的示例中,假设原始服务称为“付款”,一旦在付款方式级别重新定义职责,该名称就会过时。在现在有名为“Paypal”和“Apple Pay”的服务的平台中,旧名称“Payment”代表什么?

微服务边界的启发式方法

在不断变化的环境中,随着时间的推移,某些服务的职责不可避免地需要重新定义。对于微服务应该有多大或多小,没有任何规则。在没有最佳解决方案的情况下,基于经验的启发式方法似乎是我们最好的选择。

以下是一些建议:

  1. 如果服务的某些部分变化非常频繁,而其他部分几乎不变化,则表明该服务可以一分为二。
  2. 代码库中需要特定测试或需要更长测试时间的部分也最好自行服务,这样它们的生命周期就不会干扰应用程序的其他元素。
  3. 复杂的代码片段也应该有其服务,以避免与代码库的其他元素发生不必要的交互,这可能导致难以识别的错误。
  4. 访问数据库或队列等外部资源的代码也应该封装在其服务中:您不希望必须使用这些外部资源配置本地环境,只是为了能够启动服务,然后使用一些与外部完全无关的功能资源。

真实案例

如果上面关于支付服务的虚构示例还不够吸引人,那么这里有一个真实的案例。

欧洲之星一直在销售伦敦和其他欧洲国家首都之间的火车票。大约三年前,我与他们合作,将他们的整体架构转变为微服务架构,因此我们开发了“搜索”、“结账”等新服务。显然,在欧洲之星的背景下,术语“搜索”和“结账”提到它唯一的产品,已经销售了25年的产品:火车票。

新的微服务完成后不久,欧洲之星就做出了战略决策,成为一家旅行社,除了火车票外,还销售酒店住宿和套餐假期。创建了新服务:“酒店搜索”、“酒店结账”等,使现有服务的名称不充分,并通过提出诸如我们是否需要通用结账服务还是应该将它们分开等问题来质疑其范围?

10-20 00:26