时间: 2020-09-03 00:08:26 人气: 2276 评论: 0
软件架构虽然是个相对稳定的技术领域,但也在十年间经历了从单体应用到 SOA 再到微服务的演化过程。但在本文作者看来,自SOA架构风格提倡以来,软件架构并未有特别的突破,更多是在其之上做不断的演化迭代。为什么呢?
Everything will be alright in the end, but if it is not alright, it’s not the end YET. —— True Grit Don’t take shortcuts. Don’t ask about what does not concern you. And don’t jump too quickly to conclusions.——Three Words of Wisdom The whole is greater than the sume of all parts. The whole has the properties its part do not have. — The concept of Emergence
自从SOA架构风格提倡以来,个人觉得软件架构并未有特别突破的变革:主要是在SOA面向服务架构风格基础上不断演化迭代。基于服务的EA明确分层架构也好,微服务也罢,都是在面向服务架构基础上的适应不同的场景的迭代升级,同时DDD领域驱动也给面向服务架构设计提供了非常好的设计理念,所以我就想回归到根本:面向服务的的架构来聊聊,可能有人说老生常谈没啥意思,没关系,就当一个自己的思路整理,先聊10块钱的。
面向服务的架构个人认为我们花了非常多的精力在HOW上面,但是对服务是什么(What)和为什么我们要服务化的架构(Why)重视度和花的精力是相对不足的。
我先抛出一个观点,我觉得服务化架构的本质和西方教育界深受影响的古希腊哲学家苏格拉底的“产婆术”的教育思想本质上是非常相通的:苏格拉底的“产婆术”思想强调教育是一个“接生”的过程,教师就是“接生婆”,人们之所以接受教育是为了寻找“原我”以不断完善自身。也就是教育的目的在于唤醒而不再于塑造。同理服务化架构的本质也不仅仅在采用什么样的技术框架实现和塑造,更重要的是在于通过不停地在共创中反问、反思、反省等方式进行对业务的本质的不断追溯、抽象、综合归纳演绎,我们的每一个架构师都是服务化架构的接生婆,我们的使命是建立真正反映业务本质并驱动业务不断向前的架构。
我们是否足够深入理解业务的本质,做了足够的归纳演绎以及综合抽象,是否清晰的反应到了我们的服务化的根基:业务模型、域模型以及平台公共语义模型上?这是我们每一个参与服务化的每一个产品、架构师、TL和核心开发同学需要回答的第一个根本问题。
为了不产生概念的混淆和理解差异,我尝试先对一些基础的概念进行定义,各大组织定义各异,我选择和自己的理解更接近的一些定义,在参考各大标准定义的基础上加入了一点自己的理解。
面向服务的架构(SOA):
SOA 是一种架构风格,致力于将业务功能保持一致的服务(系统服务,应用服务,技术服务)作为设计、构建和编排组合业务流程以及解决方案的基本单元。
我们采用SOA的架构是为了什么呢?
为了更好的复用?为了更好的责任切分?为了接口和实现的分离,提升灵活性和隔离性?还是为了更好的接口分类和管理?
以上说法其实都没错,但是面向服务化的架构SOA目的是远远超过接口技术细节的设计与定义,其核心的关注点在于服务的业务内容以及内涵,而不仅仅是如何设计和实现。
同时,SOA更多的也不是如何构建一个服务,任何人都可以很容的创建一个服务,这并不是SOA的核心挑战,而是如何赋能企业构建有业务价值意义的完整业务语义的服务集合
面向服务的架构致力于在企业内的不同的业务环境内,建设业务功能驱动的服务,从而将服务组装成有价值、更高级别的业务流程和解决方案平台。
面向服务的架构的真正的价值体现在当可重用的服务被灵活组合、编排在一起来构建敏捷的,灵活的业务流程,其中敏捷体现在服务可以快速调整,独立演化;灵活性体现在服务由于其业务功能定义明确,边界清晰且功能内聚性强,同时服务具备各自独立完整生命周期,可被灵活组装。
如果面向服务架构能为企业提供了重大的价值,那么这些价值通过什么来体现的呢?
其中行为一致性和数据一致性作为服务的核心价值根基。
首先我们先定义一下服务是什么?
服务是通过服务契约的方式来提供业务功能的独立单元,同时受服务契约所明确管理。
服务是设计、构建和编排组合一个完整业务实体中业务解决方案的基础单元。服务契约指定了服务消费方和提供方之间所有的交互约定,包括:
那我们经常听到模块、组件等其他的软件构件,服务和他们有什么区别呢?其中最核心的区别在于服务本身是被明确管理的,其服务质量和性能是通过服务水平协定(SLA)被明确管理的,而模块以及组件并无此约束。此外,服务的全生命周期包含从设计、部署到增强升级和维护都是可管理的。
举例(下列内容仅做示例展示用,非适用于严格场景)
补货计算服 | 服务策略 | 服务质量 | 性能要求 |
---|---|---|---|
补货建议量计算服务 | 针对行业下商家/供应商维度的入仓货品补货建议计算 | 在销量预测符合分布要求且满足准确率水平要求的情况下,根据缺货率服务水平要求的产生的补货建议量符合业务期望的周转天数 | 10W+货品*30仓,品+仓补货及建议量<=30min |
订单创建服务 | 包含购物车下单+立即下单场景,满足所有优惠计算后的订单生成 | 订单创建成功率99.999999999% | 峰值支撑:100w单/s |
服务自身主要包含两个主要方面,第一方面也是服务最核心的方面就是服务的接口,另外一方面则是服务的实现。服务非常好的实现了接口和实现的分离。
核心点是服务如何被实现的对于服务消费方来说是透明的,服务消费方仅仅需要关心的是服务是做什么的,而不是如何被实现的。 服务可以提供在保持服务接口或者行为约定不改变的情况下,提供根据不同的行业不同场景提供各种不同的实现。 服务实现在保持服务接口或者行为约定不改变的情况下,可以自由进行升级和切换。服务实现既可以是静态的更新升级,也可以使动态路由实时切换实现,如对应到不同的行业以及不同的业务场景的自动实现切换。 不管服务实现如何升级或者按需自动路由切换,只用服务的行为和契约不会发生改变,用户也就是服务的消费者根本不会感知到任何不同。 我们可以把服务接口想象成室内普通电源国标插口,服务策略为室内非防水情况下适用,服务契约想象成24X7的220v电压供电能力(其中180V~250V 50Hz是质量要求,24x7稳定性要求,电流供给<=10A是性能要求),此国标插座(服务提供方)可以给包含与此接口匹配且符合契约的任何电器(消费方)交互并提供供电能力,支持其运转。 服务接口定义了交互的的风格和细节,而服务的实现定义了一个特定的服务提供方或者特定的业务实现如何提供其能力。 这种类似连接点/插口的设计极大的方便了更松耦合的业务功能解决方案。
服务接口与实现的构成也有两个重要的不同方面,分别是执行功能的方法和执行的信息数据。换句话说,一个服务是由一个业务服务操作集合以及对应操作的输入输出的抽象业务服务数据模型组成。这层业务服务数据模型是企业业务层次或者平台业务层次的业务实体的抽象,独立于底层数据存储与实现。此业务数据模型是和各子域密切相关联,但是超越各子域以上的,在完整的业务线或者平台层次上达成一致的业务数据模型,也就是说在各子域之间达成共识且约定的严格明确的公共模型,主要用于平台业务流程中不同域服务的交互,是平台层次统一的业务语言,我把它暂时称为平台业务数据模型。 此平台业务数据模型通常需要包含平台统一语义的业务术语表,平台各域核心实体表,平台各域核心实体交互图等。
接口与实现的逻辑构成:
理解服务化分层架构,首先要对TOGAF Meta-Model有个清晰的理解,从元模型可以看出业务服务和业务流程的上承业务,下启系统平台的核心作用,一定要深刻理解业务服务和业务流程在企业架构中的重要性,下面我把我翻译后画的版本给大家放在这里,给大家做个参考,TOGAF不多做解释,如有需要,大家可以交流,后面有时间尝试写下我对TOGAF的学习和理解。
通常情况下,我们会按照不同行业的不同的业务流程去搭建系统,如供应链最初在大家电3W行业孕育,我们按照3W的行业和业务场景搭建了平台商家相适应的计划系统;后续自营行业又根据自己的行业也搭建了自营的计划系统;后续小电数码、国际以及其他业务快速发展,跟随业务快跑的同时,也各自建立的各自的业务流程。在这个过程中,BPM为建造不同的业务系统提供非常好的抽象支撑,但是经常的结果是,BPM被用作构建了更高层抽象的,也更高效的,但是却是烟囱式的应用,而不没有更好的贡献更多的支撑到整体上能快速应对业务变化而更灵活,更敏捷的业务平台或者系统。
而这正是面向服务的架构中业务规则以及决策作为服务要发挥更大作用的地方。面向服务的架构允许我们将特定业务流程中的业务规则和业务决策抽象分离出来变成业务规则或者决策服务,这些规则和决策服务就可以被灵活应用到不同的业务流程中,从而这些服务可以被统一管理和演化升级。
BPM+SOA一起提供了支撑企业架构的完美组合。BPM提供更高层抽象定义业务流程的能力,以及与流程相关联的重要监控和管理能力;业务服务提供了支撑业务流程的核心的功能、决策以及信息。面向服务的架构则提供能力将服务组合在一起来支撑和创建灵活且敏捷的端到端的企业业务。如果只有BPM而没有SOA对于创建单独的业务应用或许非常有用,但是通常是创建的烟囱式的应用,很难扩展到企业内或者平台内不同的业务线。如果只有SOA而没有BPM虽然可以创建可重用且一致性高的服务,但是缺少将这些服务快速搭建业务流程并支撑端到端业务的能力,也无法支撑建立具有竞争力且可以随着外部竞争环境进行敏捷反应的业务。
下图显示了一个建议的的封层服务化架构图,各分层如下:
我们通常按照上述分层结构来描述平台架构或者企业内部架构,看上去好像层次结构清晰明了,但是却是不完整的,因为此面向服务的架构描述缺失了平台系统架构中一个核心部分,暨信息及信息模型分层,这一点非常之关键,往往会决定架构的成功与否。
为了使架构更完整同时也更真实,我们需要添加对应的完整信息抽象(实体模型 or 领域模型):
现在来讨论下服务化分层架构重视度并不太高的另一个重要侧面:信息架构,之所以说信息架构非常之重要,是因为信息架构与服务化架构是一个密不可分的完整的整体。我对信息架构模型进行了分层划分,下面从TOP_DOWN方向来讨论不同的分层模型。
我们初步了解的什么是服务,以及什么是服务化的分层?那如何设计服务以及服务化架构呢?下面给出基本步骤和方案。
首先,我们要理解服务化架构的整体背景。我们必须理解我们所支撑的业务和业务根本驱动力以及所有的业务流程,业务场景以及业务用例;同时对于平台系统,我们还必须理解公司的战略所赋予平台的使命是什么?我们平台中长期的目标是什么?平台的终局是什么?这些组合和在一起才是服务化架构的完整的上下文背景。这些必须要反映到我们的业务模型、平台公共语义模型和各域模型中去。
然后,我们需要提出并回答如下问题:
前面六个问题描述了整体的架构需求(包括业务和平台),而剩下的问题则描述了整个服务化架构的上下文以及引入了服务目录库的需求。我们服务不能只从单个服务的角度来看,而必须从整个服务集合的角度来反应完整的业务语义和平台语义。我们的服务集合也就是服务目录库必须具备完整的上下文语义,必须能识别出:
服务目录库的设计必须支持两个主要的设计时目标:
服务目录库中的服务可以按照服务类型以及服务角色来进行组织。服务类型请参照服务化分层架构内容里的描述;服务角色包含任务服务角色、实体服务角色和决策服务角色,请参照后面小节描述。
面向服务化的架构的其中一个成功的关键是创建一个具备完整业务语义的服务集合以便于可以方便一起进行组合编排来支撑不同的业务流程以及丰富的业务场景。
我们经常谈论各功能域要提供松耦合的服务,是因为服务间的松耦合是非常重要的,特别是通过减少服务间的依赖以便于服务可以在不同的场景中被复用,以及可以起到隔离变更影响的作用。但是如何才能尽可能的实现这个目标呢?
首先我们来看下对于服务最重要点是什么?首先就是这个服务提供了什么样的业务功能,其次这个服务对业务有价值的数据产生了那些影响。从这两个点上我们就可以比较容易得出两种类型的耦合在服务接口设计中是特别重要的:
举例来说明下:
交易服务协调所有的活动,然后依赖其他服务来帮助完成流程。交易服务依赖于或者说耦合于用户服务,商品服务,库存服务,营销服务、订单服务以及支付服务等。
为啥交易服务没有实现所有的功能?
首先是因为我们想在其他高级别流程或者服务中重用底层的能力。
第二是交易服务服务并不负责用户服务,商品服务,库存服务,营销服务、订单服务以及支付服务。交易服务只是使用它们,而不是负责实现它们。
用户服务被用作管理客户信息访问,它具有唯一的责任来提供、维护和更新客户信息,这样做的目的是为了可以在任何需要访问客户数据服务的地方重用客户服务。比代码重用更重要的是隔离或者是集中式访问客户信息,因为只有唯一的路径访问数据,数据就总是一致的,真正实现 Source Of Truth。因此,尽管有很多服务包含交易服务,购物车,订单历史等服务需要访问客户服务,通过松耦合的这种模式去管理这些依赖是比较容易被理解的。
通过创建服务来执行用户管理,商品管理,库存管理,以及营销管理等,就可以在任何可以用到的地方,执行保持一致性的这些业务功能。
敲黑板:好的服务设计并不仅仅是关注重用性,更重要的是要提供一致性,既包含功能一致性,也包含数据一致性。
那么下一个问题是你如何决定有哪些服务以及这些服务分别是什么呢?同样,你用功能分解和信息隔离组合在一起来决定服务有哪些并且各自是什么?
面向服务的架构中服务设计的问题需要跨越多个以致于所有的流程中来一起考虑。
因此,服务设计原则基本原则如下:
在服务化设计中,如何实现上述的这些原则呢?答案是提出并回答如下问题:
这些问题的答案会帮你来识别如下信息:
我们通常设计服务时候一个很大的疑惑是我的服务到底要设计成什么样的颗粒度,应该更粗粒度一些,还是更细粒度一些?答案是:没有一个统一正确的服务颗粒度标准。那怎么办?我如何设计我的服务的颗粒度呢?虽然没有统一的标准,但是我们可以依赖下面的因素来决定合适的服务粒度:
在几乎任何复杂的环境或者系统平台中,我们可以预期到多种多样类型的服务。这些服务具有不同的类型和颗粒度,可以参考服务化分层中的内容,也可以见下面的描述:
独立于服务的粒度,职责范围以及服务创建以外的另外一个重要考量或者说是侧面是:服务在服务组合或者流程编排中所承担的角色是什么?
那么怎么来区分不同的角色呢?我们使用关注点隔离的架构原则。例如,我们在构建应用中就使用了将数据同逻辑隔离作为重要的概念。这样不仅提供了不同关注点解耦的可能以及机会,而且允许采用不同的方式,在不同的地方来实现这些不同的关注点。
对业务流程进行单独管理的BPM就是一个非常好的例子,BPM作为另外一个关注点分离的例子,将业务流程方案从其他逻辑中分离出来,可以使工作流程可以在一个特定的层次或者环境内进行执行和管理, 这样就可以实现通过快速的建立新的流程模型来快速响应业务的变化。同时面向服务的架构SOA提供了将业务服务作为构建业务流程的基础构件的功能。业务规则系统BRMS同样也作为一个关注点分离的例子,将业务规则或者业务决策从其他应用逻辑中区分开来,这样业务规则和业务决策也可以在一个特定的层次被执行和管理,从而就可以很容易的被变更来支持新的业务需求。这里,业务规则以及决策服务也是面向服务的机构来暴露出规则和决策服务来支撑规则和决策与业务流程的分离。
通常我们通过较粗粒度的来定义三大类服务角色来构建不同的服务层次:
我们通过组合这些不同类型的服务角色来提供灵活的业务能力,从而用来支持业务流程内的活动。我们提供了一些基本原则来帮助我们进行服务组合以便于帮我们减少依赖,限制耦合以及最大化灵活性。
服务层次以及组合基本原则:
现在我们可以通过丰富的流程,实体和决策服务的集合,可以创建新的不同的服务组合,把规则的灵活可变的好处同服务化架构的模块化,灵活性以及重用性结合起来作为业务系统平台级别的基本架构方式。
大的规划首先要明确2-3年内的服务化的目标:是快速地灵活支撑业务快跑?还是业务支撑目的已经初步达成,准备将成功经验产品化输出到业界? 基于不同的目标的设定不同的规划框架指导:
大的规划切记事无巨细,而是根据长期规划设定明确的指导性原则和要求,在体系化的基础上鼓励协同和创新。
服务化不应该是运动式的大跃进推进,而应该是坚持试点、推广、总结、扩大试点,从而由点到面,逐步落实的方法,由各域根据规划的体系化要求,再各自情况暨各自成熟度来设定各自服务化目标,制定一个个小目标,快速迭代,敏捷式的总结推进。
服务化要从上到下从目标到落地策略统一获取共识,共识非常重要,要从技术高层到普通开发人员达成清晰明确的方向和落地体系。服务化是一个庞大的,迭代的,渐进的体系化工程,而不是一蹴而就的战役式定胜负的项目,建立共识的根本是要讲清楚服务化的目标、架构、设计、开发背后的清楚的逻辑,让每个人想的清楚,听的明白
接地气同达成共识一样,要用朴素的工程师语言讲清楚目标和逻辑,而不是拿各种看上去非常光鲜亮丽的各种名词来充当台面,讲的人解释不清楚,听得人一头雾水,没有体系化逻辑来支撑落地,最终很难达到服务化真正的目标的。
借用毛主席在延安文艺座谈会上的讲话:
“我们的文艺工作者不熟悉工人,不熟悉农民,不熟悉士兵,也不熟悉他们的干部。什么是不懂?语言不懂,就是说,对于人民群众的丰富的生动的语言,缺乏充分的知识。许多文艺工作者由于自己脱离群众、生活空虚,当然也就不熟悉人民的语言,因此他们的作品不但显得语言无味,而且里面常常夹着一些生造出来的和人民的语言相对立的不三不四的词句。许多同志爱说“大众化”,但是什么叫做大众化呢?就是我们的文艺工作者的思想感情和工农兵大众的思想感情打成一片。而要打成一片,就应当认真学习群众的语言。如果连群众的语言都有许多不懂,还讲什么文艺创造呢?英雄无用武之地,就是说,你的一套大道理,群众不赏识。在群众面前把你的资格摆得越老,越像个“英雄”,越要出卖这一套,群众就越不买你的账。你要群众了解你,你要和群众打成一片,就得下决心,经过长期的甚至是痛苦的磨练。”
服务化落地的核心力量是一线工程师同学们,一定要用朴素的工程师语言讲透讲明白,让工程师同学心中不惑,不能让工程师同学来猜,猜来猜去,很多时候目标就偏了,时间就浪费了,信心就磨散了。
服务化是一个庞大的,迭代的,渐进的体系化工程,不是快闪战,不是突袭战,是场持久战,一定要有曾国藩的“结硬寨,打呆仗”的耐心和准备,踏踏实实落地迭代推进,小步快跑,在坚持体系化思考的基础上进行持续总结改进,通过一个接一个战斗,一个小胜利接一个小胜利,一个战役接一个战役不停的攻城略地的基础上逐渐迈向成功。
一句话,高效的方式就是慢想、快干,明确目标,规划架构,设计实施方案和落地步骤都需要认真的、耐心的思考,理清头绪,搭建体系化的逻辑支撑,剩下就是执行和落地了。我们不一定缺少高执行力的人,但是一定缺少能独立思考并体系化行事的人。慢想,快干说起来容易,但做起来难,要看有没有耐心,能不能沉得住气,而不是口号式的蛮干,回头看最有效率的一定是,Think Fast, Act Slow。
总体上来说,面向服务的架构通过应用分层架构的方式来分离业务流程和底层包括运营资源在内的各种资源,来支撑业务灵活性。
面向服务的架构提供的价值以及灵活性依赖于服务分层的质量,服务可以具有各种各样的粒度和类型。服务颗粒度很重要,但是知道服务如何被使用一样重要:服务在支撑业务流程上承担了三种基本角色:任务服务角色,实体服务角色,决策服务角色。
面向服务的架构很早就作为软件业界特别是互联网架构风格取向,然而服务化却很难被真正成功的实现,原因多种多样,这里列一下一些相关的与此相关的个人的观点,不喜可以随便喷。
观点1:
服务化失败通常最最根本的问题不在于HOW:用何种技术来实现它,而在于WHAT:如何用业务本质的抽象来定义服务,定义分层,也就是首先摸摸揣在你胸口的业务本质WHY:业务模型以及域模型等,你想清楚了没有?然后再想想如何利用服务分层和服务特性来搭建牛B的系统平台
观点2:
产品同学和技术同学各自在服务化架构承担什么角色?个人观点如下: