原文题目: Untangling Microservices, or Balancing Complexity in Distributed Systems
原文地址
上篇地址
翻译: 祝坤荣
微服务
让咱们先从准确定义什么是服务和微服务来开始。
什么是服务?
依据 OASIS 规范 9,一个服务是:
通过规定好的接口提供能拜访一种或多种能力的机制
规定好的接口这部分很重要。服务的接口定义了它裸露给外界的性能。依据 Randy Shoup 10 的说法,服务的公共接口简略来说就是任何让数据进出服务的机制。它能够是同步化的,如简略的申请 / 响应模型,或者异步化的,一个生产事件一个生产事件。不管怎么说,同步或异步化,公共接口只代表让数据进出一个服务。Randy 也表白了服务的公共接口就跟 前门 是一样的。
服务是被公共接口定义的,这个定义对于定义什么服务是微服务也足够了。
什么是微服务?
如果一个服务是被它的公共接口定义的,那么 –
一个微服务是指一个用了微型公共接口的服务 – 微型前门
这条在过程式编程中被恪守的规定,现在在分布式系统畛域更加有关联性。你裸露的服务越小,它的实现越简略,它的本地复杂性越小。从全局复杂度来看,更小的公共接口会在服务间产生更少的依赖和连贯。
微接口的概念也解释了宽泛应用的微服务不裸露数据库的实际。没有微服务能够拜访另一个微服务的数据库,只能通过其提供的公共接口。为什么?因为,数据库理论是一个微小的公共接口!只有想想你能够在一个关系数据库上能执行多少种操作。
因而,再重申下,在分布式系统中,咱们通过将服务的公共接口最小化的形式来均衡部分与全局复杂度,而后服务就变成了微服务。
正告
这听起来很简略但其实不然。如果一个微服务只是有微型公共接口的服务,那咱们能够间接将公共接口限度到只有一个办法。因为这个“前门”曾经小的不能再小了,这应该是完满的微服务,对吗?为了解释为什么不这么做,我会应用我另一篇博文 11 里的一个例子:
退出咱们有如下库存治理服务:
如果咱们将它拆成八个服务,每个只有一个简略的公共办法,咱们能够失去完满的低本地复杂度的服务:
但咱们能将它们连入零碎来真正治理库存吗?并不行。要造成零碎,服务须要与其余服务交互并共享对于每个服务的状态。但它们不行。服务的公共接口不反对。
因而,咱们要继承这个“前门”并让这些公共办法能够反对服务间的集成:
完了!如果咱们通过将每个服务齐全独立的形式来优化复杂度,那么解耦的是很彻底。然而,当咱们将服务连入零碎,全局复杂度又升高了。不只是导致系统卷入了一团乱麻;为了集成 – 继承公共接口也超出了咱们原来的用意。引自 Randy Shoup,除了建设了一个小“前门”,咱们也建了一个微小的“员工专用”入口!这通知咱们一个重要的观点:
一个服务有比业务办法更多的集成办法有成长为分布式大泥球的微小可能!
因而,一个服务的公共接口能够被最小化到什么水平不只是依赖于服务自身,也取决 (次要) 于它在零碎中是哪一部分。一个微服务何时的解耦应该同时思考零碎的全局复杂度和服务的部分复杂度。
设计服务边界
“要找到服务边界太难了 … 齐全没有流程图!”-Udi Dahan
下面 Udi Dahan 说的话对于基于微服务的零碎来说也很对。设计微服务的边界很难,基本上第一次很难做对。折让设计一个适合复杂度的微服务变成了一个迭代流程。
因而,从更大的边界开始是比拟平安的 – 从上下文边界开始比拟适合 12 – 有更多对于零碎各它的业务域的常识后,再将它们解耦成微服务。这对那些蕴含了外围业务域的服务特地重要 13。
分布式系统之外的微服务
只管微服务只是最近才被“创造”进去,你仍能够在工业界发现很多有同样设计理念的实现。这些包含:
跨性能团队
咱们晓得跨性能团队是最无效的。这种团队让不同业余能力的小组工作在同一个工作上。一个无效的跨性能团队能最大化团队内的交换,最小化团队外的交换。
咱们的工业只是最近才发现跨性能团队,但工作组是始终存在的。其底层的原理与基于微服务的零碎是一样的:在团队内高聚合,团队间低耦合。团队的“公共接口”通过须要达成工作的技能来进行最小化(如实现的细节)。
微解决
我要通过 Vaughn Vernon 那经典的相干主题的博文来举这个例子。在他的博客里,Vaughn 描述了一个微服务与微处理器间乏味的类似点。他讲述了处理器与微处理器间的不同:
我发现了一个通过大小规格来帮忙确定一个处理器是中央处理器 (CPU) 还是微处理器:数据总线 21 的大小
微处理器的数据总线就是他的公共接口 – 它定义了能够被传给微处理器与其余组件间的数据量。对于公共接口有严格的尺寸规格来定义这个中央处理器 (CPU) 是不是一个微处理器。
Unix 哲学
Unix 哲学,或 Unix 形式,是一种秉承了极简主义的模块化软件开发标准和文化。22
有人可能会反驳我 Unix 哲学与我的状况不符,你不能用齐全独立的组件来组装一个零碎。难道 unix 程序不是齐全独立,而后造成一个可工作的零碎的吗?事实正相反。Unix 形式简直字面上定义了程序须要裸露的微交互操作。让咱们看看 Unix 哲学与微服务相干的局部:
第一条原理让程序裸露一个与其性能相干的公共接口,而不是与其原始指标不想关的:
让程序只做一件事并做好。要做另一件事,写个新的而不是在老程序里加新“个性”。
只管 Unix 命令被认为是彼此间齐全独立的,但并不是。它们之间须要通信,并且第二条准则定义了通信的接口如何设计:
预期所有程序的输入会作为其余程序的输出,只管可能当初还不晓得。不要让输入有不相干的信息。防止严格的列式或二进制输出格局。不要强制要求交互式命令有输出。
不只是通信接口被严格限度(规范输出,规范输入,规范谬误),基于这个准则,在命令间的数据传输也被严格限制住了。例如,Unix 命令须要裸露微 - 接口并永远不依赖于其余命令的实现细节。
那么 Nano 服务呢?
文字 nanoservice 常常是用来形容一个服务太小了。有人会说下面例子介绍的一个办法的服务就是 nano 服务。我不批准这个观点。
nano 服务用用来在疏忽了整体零碎时形容独自服务时用的。在下面例子中,一旦咱们将零碎放入方程中,服务的接口就会增长。实际上,当咱们比拟一下原来的单服务实现与解耦后的实现,咱们能够看到一旦将服务连入零碎,零碎从 8 个公开接口增长到 38 个。而且,每个服务公开办法的均匀数量从 1 涨到 4.75.
因而,当咱们又花了服务(公共接口),数据 nano 服务不再成立,因为服务被迫开始增长来支持系统的用例。
这些够了吗?
不。只管最小化服务的公共接口是一个设计微服务的好准则,它依然只是一种摸索式的形式而不能取代常识。实际上,微接口只是更加根底,且更简单的耦合与内聚设计准则的形象。
比方,如果两个服务有微 - 公开接口,它们让须要在分布式事务中协调,它们仍是相互高耦合的。
针对微 - 接口在解决不同类型的耦合,比方函数,开发,语义依然是有启发的。但那就是另一篇博客的主题了。
从实践到实际
可怜的是,咱们没有一个主观形式来量化部分与全局复杂度。从另一方面,咱们的确有一些设计形式能够优化分布式系统的设计。
这篇文章次要的内容就是想通知你在评估服务的公共接口是你要不停的问本人:
- 业务的占比是多少 – 给定服务是面向集成的 endpoint 吗?
- 这是在业务上不想关的 endpoint 吗?在不引入面向集成的 endpoint 的前提下你能够将它们拆散成 2 个或更多服务吗?
- 合并两个服务是否能打消当初为了集成原始服务而产生的 endpoint?
能够用这些准则来领导你在服务边界和接口的设计。
概要
我想最初用 Eliyahu Goldratt 的观点来总结下。在他的书里,他常常反复上面这些句子:
“ 通知我你如何度量我,我会通知你我怎么体现 ” – Eliyahu Goldratt
当设计基于微服务的零碎时,很重要的就是度量和优化正确的指标。为微服务代码库设计边界,则微小组的定义会更容易。所以,开发一个零碎,咱们要学会算账。微服务是用来设计零碎的,而不是独立的服务。
回到这片的题目 -“在分布式系统中解决, 或均衡微服务的复杂度”。解开微服务问题的惟一方法就是均衡每个服务的部分复杂度与整个零碎的全局复杂度。
援用索引
- Gergely Orosz’s tweet on Uber
- Monoliths are the future
- Microservices guru warns devs that trendy architecture shouldn’t be the default for every app, but‘a last resort’
- Monolithic Application(Wikipedia)
- The Majestic Monolith – DHH
- Big Ball of Mud(Wikipedia)
- Definition of a System
- .Composite/Structures Design – book by Glenford J. Myers
- .Reference Model for Service Oriented Architecture
- .Managing Data in Microservices – talk by Randy Shoup
- .Tackling Complexity in Microservices
- .Bounded Contexts are NOT Microservices
- .Revisiting the Basics of Domain-Driven Design
- .Implementing Domain-Driven Design – book by Vaughn Vernon
- .Modular Monolith: A Primer – Kamil Grzybek
- .A Design Methodology for Reliable Software Systems – Barbara Liskov
- Designing Autonomous Teams and Services
- Emergent Boundaries – a talk by Mathias Verraes
- Long Sad Story of Microservices – talk by Greg Young
- Principles of Design – Tim Berners-Lee
- Microservices and [Micro]services – Vaughn Vernon
- Unix Philosophy
本文来自祝坤荣 (时序) 的微信公众号「麦芽面包,id「darkjune_think」
开发者 / 科幻爱好者 / 硬核主机玩家 / 业余翻译
微博: 祝坤荣
B 站: https://space.bilibili.com/23…
交换 Email: zhukunrong@yeah.net
转载请注明。