微服务(Microservices)集成原则

在微服务的诸多优势中,最重要的动机是业务单位的规模和自主权。然而,我们仍然需要创建一个对最终用户有意义的集成体验。在为微服务之间的交互开发策略时,记住这两个目标是很重要的。这些策略可以成就或毁掉你的努力。

我们如何映射每个微服务决定了它的自主性。由有限上下文[1]或业务功能建模的微服务比基于技术能力建模的微服务更具有自主性。让我们考虑一个银行应用程序的示例。它可以具有的一些边界上下文通常是登录和安全、配置文件管理、事务服务(一种借贷服务,因为它们紧密相连)、支出报告和外部服务,比如信用报告检查或奖励检查。这些上下文可能有许多类似的技术实现:例如,日志记录。但是,如果我们将日志记录创建为自己的服务,那么几乎所有其他服务都将依赖于它。它可以成为一个关键:你把它拿下来,生意就停止了。相反,我们可以将日志实现推入一个库,根据上下文创建服务,并尽可能使用日志库。

用自己的数据库映射垂直业务片中的服务只是开始。我们仍然需要以一种创建内聚体验并在这些服务之间共享数据的方式来集成它们。我们如何在保持自主性的同时做到这一点?在研究如何进行集成之前,我们必须首先评估将影响集成决策的各个服务之间的无数交互。

松散耦合和高内聚

为了确保自主性和可伸缩性,各个服务应该具有高度的内聚性(对类似功能进行分组)和松散耦合的[2]。计算机科学中的“耦合”描述了模块[3]之间的相互依赖关系。松散耦合的系统以消息的形式共享定义良好的数据,仅此而已。它们不关心状态、正常运行时间、性能水平或技术实现。

从我们的银行示例中可以看出,如果信贷和借贷服务是分开的,它们就会变得非常依赖对方,因为它们往往会影响相同的数据部分:您的账户余额。如果显示的余额不一致,哪个是对的?这些服务必须非常一致,这会导致大量的网络通信。相反,我们可以将这两个功能合并到一个内聚服务中,从而避免复杂性。

迭代的业务边界

过多依赖于其他服务的数据、实现和uptimes可能是错误或过时的业务边界的征兆。业务总是在变化,这就是为什么我们需要周期性地回顾边界假设。这确保我们没有创建太细粒度的服务,即nanoservices[4]。这些毫微服务往往有支离破碎的逻辑和较差的性能。它们增加了很多维护开销。基于技术实现而不是业务边界的水平服务落入了这个陷阱。信贷和借贷功能划分到它们自己的服务中也符合这一点。没有必要打破这种凝聚力,在他们之间引入一个网络。

了解网络的限制

如果有可能发生故障,我们需要有一个计划来处理它,这是一个很好的工程实践。网络通信是[5]的一个主要例子。跨越业务边界的服务通过网络相互连接。我们需要了解其影响,因为在业务边界之外,维护团队的控制范围非常小。因此,我们应该尽可能减少网络通信。例如,在银行应用程序中,我们需要让支出报告服务知道借方交易。不正确的实现会调用该服务,询问是否可能进行这种操作,或者可能对输入参数执行验证,然后报告余额更改。这两个可以很容易地合并成一个,可以将颤振减少一半。这个想法是基于告诉,不要问[6]原则。所有这些看起来都很小,但是这些小事情加起来很快。理解将api放在HTTP上的含义是很重要的。

有面向契约心态

一直考虑API的消费者是很重要的,无论我们决定采用哪种集成。考虑到服务使用者而编写的代码具有更好的封装性,并很好地隐藏了实现细节。在这方面,测试驱动开发可能会有帮助。有了TDD,我们可以先编写消费者契约,然后编写代码来满足这些契约。PACT[7]可以帮助我们在服务之间共享这些合同。

在没有以这种方式编写的代码中划分界限变得很困难,例如,基于CRUD或基于存储库模式的api。它们与数据库实体有关。它们跨越产生更紧密耦合的业务功能。在这一点上,首先重新设计它们是一个更好的主意。

了解CAP定理和数据库技术

分布式系统的主要目标是更好地进行扩展。在理想的情况下,松散耦合服务共享的数据可以毫不费力地进行复制。这将需要最佳的一致性、可用性和分区公差,这意味着1)每个阅读器都获得最新的写入,2)每个请求都收到一个无错误的响应,3)由于网络分隔了微服务,它们必须处理任意数量的被删除的消息。然而,这受到CAP定理[8]的限制,它说明在任何系统中,这三个条件中只有两个是最优满足的。

因为可用性和分区公差在分布式世界中至关重要;我们必须处理较弱的一致性,如下所示:

然而,一致性本身有很多层次。Azure Cosmos DB等分布式数据库技术支持其中的五种[9]。另一方面,谷歌云扳手技术通过声称提供高一致性以及可用性和分区公差[10]来挑战CAP定理。在决定系统的数据库技术时,我们需要记住这些条件。

理解事务和事务边界

跨多个服务的分布式事务很难得到正确的处理,因为在提交数据[11]之前,它们要经历多个阶段。它们需要编排,这使得系统非常脆弱。所有这些麻烦都是为了到达一个不能很好地进行扩展的地方,并且不同服务之间的数据库选择可能不同。现在怎么办呢?

相反,我们可以让Cosmos DB或Cloud Spanner等新的数据库技术处理幕后的复杂性。如果这不是一个选项,我们可以在服务边界内支持事务性保证,并使用Outbox模式生成事件,供其他人使用[12]。使用我们的银行示例,当用户更改配置文件中的电话号码时,我们可以在用户配置文件服务自己的数据存储中提交该信息,并生成事件供其他系统使用。成功使用该消息后,我们的通知服务可以通知用户帐户更改,如下图所示:

小心使用同步(阻塞)API

在提供服务之前,我们必须考虑到网络的局限性。跨服务的同步调用通常是通过HTTP进行的,如果HTTP服务宕机会发生什么,管理起来就会变得非常棘手。我们怎么知道它下降了?我们如何处理失败?如何同步回滚应用的更改?缓存位于何处?将管理多少类型的缓存?每一个消费者?每一个电话吗?所有这些复杂性都可能导致复杂的体系结构,每个人都相互调用。

同步服务对响应时间有更高的期望,这使得它们在扩展和维护方面更具挑战性。少即是多。同步API调用通常会导致更协调的解决方案。有时,我们需要物理障碍来防止不正确的用法潜入系统[13]。编配有什么问题?我们能做些什么呢?

考虑编排多于编配

编制(orchestration)和编排(choreography)是常用于描述“合成Web服务的两种方式”的术语。虽然它们有共同之处,但还是有些区别的。Web服务编制(Web Services Orchestration,WSO)指为业务流程(business processes)而进行Web服务合成,而Web服务编排(Web Services Choreography,WSC)指为业务协作(business collaborations)而进行Web服务合成。

任何需要大量集中管理的系统或任何扮演这类角色的服务都可能成为问题。它们变得太重要而不能下降。一切都通过它们,增加了系统中的耦合。这种高度协调的方法称为编排。相反,编排好的方法让服务决定在事件发生时做什么。这些服务不需要中央经理的支持。回到银行应用程序示例:在从您的帐户中扣款时,transaction服务可以调用Rewards服务,后者可以调用Credit Score服务,并以通知结束它。在本例中,事务服务处于扮演交警的一切中间。相反,它可以只创建一个“帐户余额更改”事件,并让其他服务订阅这些事件并独立完成它们的操作。后者是一种更加松散的方法——即使信用评分服务宕机,仍然可以发送通知。

经过编排的方法可以区分部分宕机和完全宕机,从而使服务本身更加健壮。

Tying It All Together

考虑到您的服务结构和它们所继承的复杂的交互网络,这是构建健壮的微服务体系结构的第一步。软件工程中没有灵丹妙药,但是这些原则都是构建对服务之间交互的充分理解的基础。

References

  1. More on bounded contexts
  2. Service definition from SOA patterns book
  3. This article does an excellent job explaining different levels of coupling
  4. More on the nanoservices antipattern
  5. Read about the fallacies of network computing
  6. The"Tell, don't ask principle" explained with C# example
  7. Details on PACT
  8. CAP Theorem explained
  9. Consistency levels supported by Azure Cosmos DB
  10. Google Cloud Spanner
  11. Distributed transactions two-phase commit protocol
  12. Learn about Outbox Pattern
  13. Hear Eric Evans' argument for physical separation of services in his GOTO Conference talk
  14. The routing slip pattern for messaging can also lead to more choreographed solutions

要了解更多关于在分布式系统中处理网络计算谬误的知识,请查看Headspring的首席架构师Jimmy Bogard的视频:Building Distributed Systems.

原文发布于微信公众号 - 程序你好(codinghello)

原文发表时间:2018-08-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏SAP最佳业务实践

SAP最佳业务实践:ETO–项目装配(240)-6审批 WBS 要素

image.png CJ20N审批 WBS 要素 为确保预先采购(下个步骤),WBS 要素的状态必须为 已释放。 角色项目经理 后勤®项目系统®项目®项目构造...

39660
来自专栏java一日一条

高并发系统的设计及秒杀实践

一个大型网站应用一般都是从最初小规模网站甚至是单机应用发展而来的,为了让系统能够支持足够大的业务量,从前端到后端也采用了各种各样技术,前端静态资源压缩整合、使用...

39530
来自专栏互扯程序

IaaS,PaaS和SaaS,QPS,RT和TPS,PV,UV和IP到底是什么意思?

今天我们来讲讲什么是云服务,云计算的三种服务模式有哪三种,我们经常评估服务的性能指标都有哪些,分别是什么意思,平时“那些人”说的QPS是什么,TP是什么,日活又...

27930
来自专栏华章科技

GitHub 到底为啥这么受欢迎?我们为你整理了一份使用攻略

导读:GitHub,全世界开发者的安全空间,在这里,你可以分享你的代码为大家所用,也可以和全世界的开发者一起共建完善你的代码。在这里,你可以学习借鉴前辈的经验快...

16240
来自专栏FreeBuf

2016 黑客必备的Android应用都有哪些?

免责声明:本人所发布的此份清单仅供学习之用。我们不支持读者利用其中的任何工具进行任何不道德的恶意攻击行为。 ? 根据业界的一系列评测以及亲身经验,我们整理出了...

22780
来自专栏北京马哥教育

关于泰捷商城项目与如何做一个高可用的网站

hi 各位, 上两周一直都在做泰捷商城这个项目。这个项目的目的就是卖泰捷出品的WEBOX。这是我第一次做有关电子商务的网站。各种头绪。其实原始需求很简单,只卖一...

395120
来自专栏AI研习社

GitHub 到底为啥这么受欢迎,我们为你整理一份使用攻略

GitHub,全世界开发者的安全空间,在这里,你可以分享你的代码为大家所用,也可以和全世界的开发者一起共建完善你的代码。在这里,你可以学习借鉴前辈的经验快速提升...

10620
来自专栏IT大咖说

MySQL 高扩展架构构建百万在线系统实践

20730
来自专栏Golang语言社区

优酷、YouTube、Twitter及JustinTV几个视频网站的架构

优酷视频网站架构 一、网站基本数据概览 据2010年统计,优酷网日均独立访问人数(uv)达到了8900万,日均访问量(pv)更是达到了17亿,优酷凭借这一数据成...

1.8K70
来自专栏SAP最佳业务实践

SAP最佳业务实践:ETO–项目装配(240)-14开始生产

CJ20N开始生产 image.png 在此步骤中审批 WBS 要素生产。 角色项目经理 后勤®项目系统®项目®项目构造器 1. 在工作清单中选择相关项目 (...

40360

扫码关注云+社区

领取腾讯云代金券