作者:王清培(Plen wang)(沪江应用架构师)
本文原创,转载请注明作者及出处。

背景介绍

最近一段时间公共业务平台在进行大面积的重构,对原来的技术栈进行迁移,逐渐往java、go、node.js等开源、自由为主的技术体系中过度。

虽然这主要是替换技术框架,但也是我们应用系统进行重新设计、业务流程重新梳理的一个好机会,我们将利用这次机会来重构之前发现的一些问题。

Martin Fowler大师《重构》一书中有说过一句话,大概意思就是,“每次对原有系统进行修改调整的时候是一个非常好的重构契机。”

对一个正在运行良好的系统进行重构机会不多,这种需要对系统进行适当的修改或者调整的时候,可以借机重构。如果总是不抓住这样难得的重构机会,就意味着积累的技术债务永远偿还不了,最后频繁的破窗效应、墨菲定律。我们正视前行的道路上欠下的技术债务,把握恰当的时机及时偿还,这样才有可能不会因为技术包袱影响系统建设,影响业务发展。这些在George Fairbanks 大师的《恰如其分的软件架构》一书中讲解的很深刻,最重要的一条就是“风险驱动”的架构设计原则,一定要先识别出风险,针对风险排好优先级及时重构解决。

我们还面临着一个最大的问题就是,需要一边支持业务高速发展一边进行系统重构,更要命的是还需要支持各业务线进行各种大促活动,配合进行核心交易系统压测等等,可想而知这种压力还是不小。

而且我们是沪江集团的公共业务平台,我们是服务于沪江集团所有业务线,包括B2C业务(沪江网校)、直播业务(CCtalk)、外部订单业务(开放平台)、UGC(沪江问答)、批量导入订单(TPS峰值较高)等核心业务。

大家可能对传统电商的业务比较了解,但是对教育行业的类电商业务可能不是很了解,两者之间最大的一个区别就是在商品的标准化上。教育是以服务为主,不是一个简单的买卖商品的过程,而是一个智能推荐的过程,所有的商品都是需要基于用户之前的学习数据来动态生成,也就是说,公共业务平台的商品系统中的商品是动态变化的,没有固定属性的商品,商品的属性一直随着数据积累在进化。

这就带来一个巨大的挑战,因为一旦不是基于一个固定标准的商品来进行交易系统、商品系统、营销系统、商户清结算系统等核心系统设计时会面临着一个极大的抽象难度,必须建立起一套庞大且可以落地的抽象模型出来,足以容纳那些变化万千的业务模式。这方面的系统建设还没有太多成熟的模式可以参考,这是一个考验你综合技术能力的时候,光有一个“具体”的技术是解决不了这种问题域的。

这个背景介绍主要是为了能够与读者达成一个基本技术讨论的上下文环境,目的是为了在讲解本文主题的时候大家在一个频道上,这样才不会浪费大家宝贵的时间。

通过背景介绍,至少我们达成以下共识,我们正在做系统重构,业务主要是提供服务型商品,背后需要很多智能化的支持,同时我们是平台型的系统,所以我们会陆续面临平台型系统所碰到的所有问题。

本文仅仅代表个人对应用架构、软件工程的一些独立思考的总结。

微服务怎么来的

把一个业务系统设计好,这本身所面对的问题域就是偏业务分析、业务设计。大部分的时间都是在根据对业务的理解来进行抽象建模,搞清楚边界,站在一个较高的角度看待问题。(这在架构设计领域常被称为“上帝视角”)

受当下比较热的技术之一微服务影响,大家都在谈论我们要打造微服务架构。当我们都沉迷在微服务的技术中时,会主观的倾向性的用微服务来辅助你的系统建模,也就是将微服务的方法论提升到了系统分析的战略层面,这将直接决定了系统架构建设的方向。

所以由此我花了点时间反思了微服务,我们必须彻底的看清楚它的来龙去脉,这样才能把它用在合适的地方。要想搞清楚微服务是什么并不简单,需要很多证据和线索,来帮助你辩证、推理你的判断。

微服务的提出者是本章前面提到的Martin Fowler,他是世界软件大师,Thoughtworks首席科学家,著作颇多。如果你读过他的一系列经典书籍的话,你应该知道他是“软件”大师,他不是类似“JAVA并发”大师Doug Lea,他们是不同领域的大师,所解决的问题域是不同的。确定这一点很重要,这可以让你明白微服务是由谁提出的,提出来用来解决什么类型问题域,这是重要的线索之一。

Martin Fowler与太多东西有关系,他与Robert C.Martin是我们在应用系统建设领域接触最多的大师,Robert C.Martin《敏捷软件开发-原则、模式与实践》荣获Jolt大奖。还有一位大师不得不提,《UML与模式应用》作者Craig Larman,他的GRASP也是经典中的经典,不可错过,绝对是武装你应用架构能力的重要武器。

如果你是一名应用系统领域建设从业者,你应该不会错过大师们的经典。他们三个大师都会经常性的出现在一些经典书籍的推荐序中,如,在Craig Larman的《UML与模式应用》的推荐序中,第一个就是Martin Fowler。

《UML和模式应用(原书第3版)》的结构和重点建立在作者多年教授和培训成千上万学生掌握OOA/D的经验之上,它提供了一个精炼的、已证明的和高效率的掌握OOA/D的学习方法。

  “人们经常问我,介绍OO设计的图书是哪一本。读过《UML和模式应用(原书第3版)》之后,我毫无保留地选择了它。” 

  ——Martin Fowler,《UML Distilled》和《Refactoring》的作者

还有很多为了解决软件复杂性而作出努力的大师,像Peter code建模大师,他发明了彩色建模,让我们能够用不变的方式勾勒、描绘出任何复杂的领域,像“实体”、“角色”、“描述”、“时刻时段”,他的著作《彩色UML建模》非常经典。此书里的一个经典分析方法就是:“某个角色的对象,在某个时间里、某个场景下做了某件事情,触发了某种事件(event)”。

比如:会员等级Level1的用户plen,2017年5月10号上午10:30分、在沪江网校的商城里购买了新版雅思7分冲刺【5月班】课程,触发了创建订单事件。

当你掌握了这种巧妙的方法之后你会喜欢上业务分析。一般人不会意识到“行为”是跟着角色走的,而是下意识的认为行为是跟着对象走的。请仔细揣摩这句话,看你能否搞清楚,这是系统分析中典型的问题,“职责分配”,这也是应用系统架构中的致命环节。

提示:你只有在公司才具有打开公司商业文件的权利,你只有在家里才可以和家人很亲密。

这里面隐含的意思就是,“角色”赋予你的行为,你只有是公司的“员工”角色的时候才可以进行公司商业文件的浏览权限。你只有是“爸爸”或者“老公”又或者“儿子”的时候才可以和家人亲密无间。在大街上搂搂抱抱的总是不太和谐,问题就在这里。你在大街上所扮演的角色是一个国家的公民,是有具体的行为准则的。所以角色决定了你的行为。

还有DDD(领域驱动设计)之父Eric Evans,DDD基本上是现代应用系统架构中必不可少的技术之一,包括阿里巴巴都在越来越多的运用DDD设计复杂的业务系统(你可以通过他们的招聘JD中发现)。DDD通过将问题域进行了设计抽象、通过将一个庞大的问题域如何进行子域的划分,又如何识别出这些子域的立体关系,而不是上下关系,识别出落地的限界上下文,上下文的边界交互模式,领域事件的影响、事件追溯(Event sourcing)等等。DDD里面明确了几个重要的东西,“战略模式”、“战术模式”、“问题域”,当我们进行系统分析和建模的时候是运用战略模式的时候。大多数时候我们错误的使用了战术模式来解决战略问题,你无法用战术层面的技术解决战略层面的问题。

DDD里面有很多突破性的技术,比较有意思的“事件驱动”、“事件溯源(event sourcing)”。

DDD强化实体,实体与实体之间的协作是通过event触发,这里又与actor模型类似,每个actor即是一个独立的微对象。

而在micro service里 服务尽可能小,服务之间也在强调事件驱动,SOA里也在提EDA架构。

问题的关键还是event怎么来,event都是特定domain的,event不会无故产生。所以得用DDD来解决event的抽象问题。

大家可能对event sourcing不是太了解,但是如果你对redis的AOF持久化了解的话,就大差不离了,redis也通过对key的操作形成一系列的event,然后通过key event来追溯数据的生命周期。

还有一些建模界的大师,像SOA大师,Thomas Erl,也是著作颇丰,他的书里有很多用SOA来建模企业整体信息架构的思路,所以SOA不纯粹是一个RPC,他是代表一整套技术落地框架。

到此,你可能会好奇,这些与微服务有啥关系。先别急着下结论,这些都是用来搞清楚微服务是什么的重要线索。

我们是什么,工程师,而不是发明或者科研人员,工程师讲究严谨、追溯、分析、看历史、看未来、找规律,需要找到证据来证明我们的推理,而不是人云亦云,要不然没有说服力,没有独立思考能力,在实施的时候要么都对要么都错,无法进行思维的碰撞。

Martin Fowler、Eric Evans 这两位大师就我个人而言意味着应用软件开发界最高领袖和方向盘(这是个人信仰、和崇拜,谁让我是他们的粉丝),Martin Fowler 的《企业应用架构模式》是软件分层架构的思想最开始的地方。Eric Evans 是个伟大的突破者,正在征服软件复杂性问题,《领域驱动设计—软件核心复杂性应对之道》是我读过的众多书籍中感触最大,最让人深思的书。

经过上面的分析和追溯,我想表达的是这样的一个构思导图:(图1)

微服务从哪里来,要去哪里

上图中从最左边开始,一直到最右边,是我在学习应用系统架构过程中总结出的一个大概技术发展或者是相互影响的关系。这些东西模糊着看,在历史上发生的事情边界并不总是那么明显清晰,都有互相影响的作用。此图主要是围绕着一些本人学习过程中收集的一些技术影响力比较高的人来叙述,并不一定完全正确,能表达我们分析的思路即可。为了只是能将这些东西串起来推理微服务的由来。

图的最右边是Martin Fowler提出微服务的时候,看到这幅图的时候你应该能大致的明白,其实微服务的提出者是用它来解决什么问题的,这里还不能完全对微服务的由来下个结论,因为还有一部分内容我们没有分析。这里还有一个有力的证据可以证明,目前微服务书籍里评分最高的就是Thought Works公司技术专家编写的《微服务设计》由图灵出版社引进国内出版。在仔细看下书的目录你会惊讶的发现微服务的落地需要DDD来辅助的,这起码在建模阶段是需要借助DDD强大的战略模式来支撑的。所以,这里也证明了,微服务不是简单的指将服务尽可能的拆小,然后一个RPC框架搞定了。这太粗糙了,无法落地的,会有一系列问题出现,比如,分布式事务问题、数据生命周期问题、数据延迟问题、抽象混乱问题等。抽象的工作做不好,落地的时候就会比较混乱,不易于扩展:(图2)

微服务从哪里来,要去哪里

如果用TOGAF的框架来划分企业整体架构体系的话,至少微服务的技术栈在应用架构层是有明确的技术应用的,而不是全指系统架构层的某个具体的技术,如,docker、RabbitMQ、RPC之类的中间件。

如果大家仔细思考过你所学的应用技术在整个软件工程的生命线上的发展关系时,你应该能发现一个规律,就是任何一个方法论的出现都会有两个层面的东西,“识别问题域对问题域进行建模”的方法,最后才会谈“如何落地的事情”。这是两个大的层面问题需要解决,战略层面、战术层面。

所以技术都要用两个层面来看,具体讲就是分析、设计、建模,落地实施方法。这其中包括如下几个比较重量级的技术体系,TOGAF 企业信息架构框架、DDD 领域驱动设计、SOA 面向服务架构、GRASP 通用软件职责设计模式、彩色建模—四色原型模式。GRASP主要是辅助职责设计,四色原型主要是捕捉实体的事件发生序列,不会让你丢失关键业务场景。

这些技术、方法论、模式并不是纯粹的理论,而是有很多比较精妙的思想在里面,我们看下上述中他们是怎么划分两个层面来看问题的:(图3)

微服务从哪里来,要去哪里

学习搞懂这些模式,都是希望能够让我们不仅正确的做事,还需要做正确的事情。这些软件大师不是在重复造轮子,而是软件工程界一直有太多问题需要解决,而且问题是源源不断的出现。

那么这些应用技术到底位于整个技术栈的什么位置,其实整个技术栈用分层来看,比较好理解:(图4)

微服务从哪里来,要去哪里

现在技术体系基本上分为三大类,应用架构、系统架构、中间件架构,当然还有运维架构、数据架构,后两者跟我们文章主题关系不是很大,这里暂且先不谈。这些在美国著名的TOGAT架构框架技术体系中讲解的比较清楚,可以适当参考。 我不打算罗列太多技术概念,只想表达微服务这个技术是在应用技术栈范畴,跟其他的应用技术一样都是具有系统分析、建模的能力,并不是一个纯粹的框架或技术,而是一个综合性的架构模式。

微服务是进化出来的

由此可以得出一个结论,微服务是进化出来的。其实纵观软件研发中的所有技术,大多都是进化出来的,很少突然出现一个跟之前所有技术不想关的技术。只不过理论性的知识容易被忽视,大多的技术人员喜欢直奔主题,动手敲敲就是一个微服务,其实只是运用了微服务技术体系中的部分技术。

我们一直有这样的困扰,计算机领域的知识学习一直有一个难点就是:“解释一个概念需要用另外几个概念来解释,但是解释另外几个概念还需要其他概念来解释”,这不就是计算机领域的发展规律吗。所以我们都在讲究聚焦领域,每个领域都是深不见底,都有他的知识体系,都有他的技术栈。

由于时间关系,我并没有把所有的线索和证据都罗列出来,其实还有很多东西都是和微服务有关系的,至少说微服务都是需要借鉴这些东西落地,比如,微服务中提到了服务的集成和编排,这些东西在SOA、DDD中都存在,很难说这是微服务的东西还是SOA、DDD的。所以都是互相借鉴和参考,再进一步演化,慢慢的就进化出一些具有代表性的技术概念。

微服务不是银弹

当我们搞清楚了微服务是什么之后,就有助于我们进行运用了。首先可以肯定的是,微服务不是银弹,他解决不了所有问题,之前存在的问题依然存在。当我们想要尽可能的使用微服务架构时,那么我们紧接着就要回答别人提出的一系列在SOA架构中同样存在的问题,就要搞清楚如何回答别人提出的服务边界怎么划分问题,如果有GRASP、四色原型等辅助你来分析、设计,会工程化、科学化很多。

其实架构做了久了大家会发现一个潜规则,就是有时候方案没有明显的对与错,而是说服力的问题。你的方案是否经得起推敲,经得起别人的提问,能否回答别人的疑虑。

所以当你将这些应用技术了然于胸之后,你大可不必说出来,而是稍加转换下就可以慢慢影响你的架构方向。

总结

由于时间关系,我有很多技术点没有展开,主要是为了考虑阅读时间问题,我们将不间断的分享重构过程中遇到的一系列问题。这其中会包括运用新技术,同时也会包括对以往经典问题的反思。

希望这篇文章能够让你对微服务有一个不一样的认识,主要是知道他位于整个技术栈的什么位置,这有点抽象,但是软件本身不就是抽象中抽象,设计中设计吗,软件开发不就是在创造世界吗。

软件开发是一个综合性的问题,我们无法用战术层面的技术来解决战略层面的问题,也无法用战略层面的技术来解决战术层面的问题。是技术就一定有适用场景,只有搞清楚某个技术的来龙去脉才可能避免滥用。

最后,虽然文章不算太长,但是文章中包含的技术面还是比较广的,要想搞清楚,需要花点时间逐个研究一番才能把这些串起来,形成综合的技术体系。谢谢。