模块 vs. 微服务

应用模块化系统设计原则避免微服务的操作复杂性。

已经有很多地方说过从单体应用迁移到微服务。除了动动嘴皮子外,好像也不需要花费很大的精力就能把单体应用拆分为微服务。但是这种方式真的对你的组织是最好的选择吗?当然也有很多缺点去维护一个混乱的单体应用。但是经常有个醒目选择被忽略:模块化应用开发。这篇文章,我们将探讨这个并展示它与构建微服务的关系。

Microservices for modularity

“有了微服务我们的团队终于可以独立开发” 或者 “我们的单块太复杂了,都拖慢我们了”。这些说法仅仅是众多理由中的一点导致开发团队开始使用微服务。另一个原因是需要扩展性和弹性。似乎开发者们渴望一个模块化的方式进行系统设计和开发。模块化在软件开发里可以总结为三个原则:

  • 强封装: 在组建里隐藏实现细节,降低不同部分的耦合性。团队可以独立工作来解耦部分系统。
  • 好的接口定义: 可能隐藏不了所有的,所以组件之间好的定义和稳定的APIs 是必须的。一个组件可以被任何符合规范的接口替换。
  • 显示依赖: 拥有一个模块化系统意味着完全不同的组件共同工作。最好有一个好的方式描述他们的关系。

微服务应该知道这些原则。一个微服务可以通过很多方式实现,只要为其他服务暴露了好的接口定义(经常是REST API)。它的实现细节在服务里面,并且可以改变不会影响到系统和协调。各个服务的依赖通常在开发期间不是显式的,可能会导致服务在运行期编排失败。我们可以说最后一个模块化原则可以使用在大多数微服务架构里。

所以,微服务遵循这些重要的模块化原则,会有实实在在的好处:

  • 团队可以独立工作和扩展。
  • 微服务可以更下更专注,减少复杂性。
  • 服务可以在内部里改变或者替换,不影响全局。

为什么不喜欢?好吧,只要你已经从单块应用(虽然有点臃肿)到微服务的分布式应用。就会带来超级操作复杂性。突然,你需要持续部署不同的服务(可能是容器化)。新的问题:服务发现,分布式日志,跟踪等等。现在可能就是分布式计算谬论。接口的版本和配置管理成为了主要关心的。这个列表还将会继续。

原来处理微服务连接有多复杂,组合各个微服务的业务逻辑就有多复杂。为了使用微服务,不能只是拆分单块应用。而在单体应用代码库里的“面条代码”是有问题的,在这些问题里改成微服务的网络连接更痛苦。

模块化选择

这是否就意味这我们要么使用混乱的单体应用,要么淹没在微服务的复杂性里了吗?模块化可以通过其他手段实现。重要的是我们可以有效的在开发期间实现和定义边界。但是我们也可以通过创建好的结构的单体应用实现。当然,这意味着我们可以接受任何从编程语言里得到的帮助和开发组件定义模块化原则。

比如,在Java里,有很多模块化系统可以帮助结构化应用。OSGi是最著名的一个,但是随着Java 9的发布,原生模块系统已经加入到Java自己的平台里。模块化现在已经是语言和平台的一部分作为一等构造。 Java模块可以在其他模块上表达依赖,发布类实现的强封装接口。甚至Java平台已经可以使用新的Java模块系统模块化。可以从Java 9 Modularity书里了解Java 9的模块化。

其他语言也提供了相似的机制。比如JavaScript在ES2015里获得了模块系统。在这之前,Node.js也为JavaScript后端提供了非标准的模块化系统。但是,作为一个动态语言,JavaScript对于 执行接口类型和模块之间的封装不是很强。你可以使用微软的TypeScript获得这块的优势。.Net框架和Java一样是强类型,但是还没有一个直接和Java模块系统相等的强封装和程序集里的显示依赖。仍然,好的模块化架构可以通过控制反转实现和创建逻辑关联程序集。甚至C++都考虑在未来的修订添加模块化系统。

当你很想在你的开发平台使用模块化特性时,可以像之前提到实现微服务的模块化好处。本质上,模块系统越好,在开发中就越有帮助。不同的团队解决不同的部分,只有定义好的接口是团队接触的点。仍然,部署时模块都在同一个部署单元里。这样可以防止大量的复杂性和部署与管理微服务相关联的成本。当然,这意味着你不能再不同的技术栈里实现模块。不过你的团队真的需要使用不同的技术栈吗?

设计模块

创建好的模块和创建好的微服务都需要严格设计。一个模块应该塑造一个有界限的域的上下文。如果错误的决定了微服务的边界,代价是昂贵的。模块边界在模块化应用里是容易改变的。类型系统和编译器通常支持重构模块。重写微服务边界设计到很多内部个人沟通防止不会再运行时挂掉。说实话,你有多少次在第一次的时候就能设定好边界,或者即使是第二次?

在许多方面,模块在静态类型语言里通常为定义好的接口提供好的构造器。调用一个其他模块暴露出来的类型接口比调用微服务提供的REST端点更加健壮。REST + JSON是很常见的,但毕竟在编译检查语法里不是一个好的互操作性方式。而且通过网络(反)序列化并不是免费的,甚至更加黯淡。更多的是,许多模块系统允许你在其他模块里传递你的依赖。当这些依赖不合规,模块系统会禁止它的。而微服务之间的依赖只会在运行时实现,给调试系统带来困难。

模块同样在代码所有权利是自然单位。团队可以在系统为一个或者多个模块负责。唯一需要与其他团队分享的是他们模块里的public API。在运行期间,相对于微服务,几乎没有隔离。毕竟都运行在同样的进程里。

没有理由为什么一个单体里的模块不能像好的微服务一样拥有自己的数据。通过定义好的接口或者信息在模块直接共享数据,而不是同一个数据源。与微服务最大的不同是,它都是在同一个进程里。最终一致性问题不应该被低估。在模块里,最终一致性是成熟的策略选择。或者你可以只是逻辑地分开数据,但存在同一个数据源里并且仍然使用跨域事务。对于微服务,没有选择:最终一致性是给定的并且你需要适应。

什么时候你才需要微服务?

所以到底什么时候适合转向微服务?直到现在,我们主要集中在如何通过模块解决复杂性。对于这个,微服务和模块化应用都应该解决。但是除了这个以外还有其他需要解决。

如果你的团队像Google或者Netflix的规模,完全可以拥抱微服务。你有能力去构建你自己的平台和工具,并且工程师们拒绝任何合理的单体方式。但是大多数的都没有这个规模。即使你认为你的团队有一天会成为十亿级的独角兽,从一个模块化的单体应用不会有伤害。

另一个适合使用微服务的理由是,不同的服务适合不同的技术栈实现。同样,你必须有规模来吸引人才在这些不同的堆栈并且保持这些平台上运行。

微服务可以独立部署系统的不同部分,有些在大多数模块化平台里很难甚至不可能。隔离部署给系统添加了弹性和容错。此外,每个微服务的扩展特性可能不同。不同的微服务可以部署到合适的硬件上。虽然模块化单体应用也可以扩展,但是所有的模块一起扩展。这不总是最好的,但在实践中,你可以通过这种方式走的很远。

总结

能找到一个中间项总是最好的选择。选择这两种的方式,最好是取决于环境、组织和应用本身。为什么不从模块化应用开始?你可以稍后迁往微服务。然后,不是动手清理单体应用,你已经有合理的模块边界。不是独家的选择:你同样可以使用模块内部构造微服务。那么问题来了,为什么微服务需要“微”?

即使你离开单体应用,服务不需要小到不用维护。接着,在服务里使用模块化原则允许他们超过微服务的复杂性里扩展。真正省成本的是减少架构里的服务数量。模块能帮助构造和扩展服务就像他们能帮助构造一个单体应用。

如果你追求模块化的好处,就不要把你自己局限于微服务里。探索进程内模块化特性或你最喜欢的技术堆栈框架。你会加强你的模块化设计能力,而不是不得不依赖于约定来避免面条代码。好好考虑你是否想成单微服务的复杂性。有时候你不得不,但经常你能找到更好的方式。

转自:https://www.oreilly.com/ideas/modules-vs-microservices

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容