从1到2000个微服务,史上最落地的实践云原生25个步骤

作者:微信小助手

发布时间:2021-09-09T21:25:11

在上一篇文章以业务为核心的云原生体系建设中,我们给出了一张云原生体系建设的总图,并且从演进的角度讲述了云原生落地的三个阶段。


有的同学留言说,还是不够落地呀,所谓“听了很多道理,还是过不好这一生”,同理“看了很多文章,还是落地不好云原生”。


从今天这一篇开始,我们开始落地篇,从此会进入大量的技术细节,学了落地篇,基本可以回去编码落地了。


其实我们在很多的技术大会上,看到的都是分层架构图,就像上一节我们分的六个层次一样,这容易给希望落地云原生的企业造成误解,因为大部分公司的云原生体系的建设都不是按层次来建设的,不会IaaS完全建设完毕,再建设PaaS,一定是根据业务的演进,交替迭代出来的。

 

一定是业务遇到问题了,需要底层的技术,底层技术提升了,促进业务的发展。如下图所示,应用层和技术底座之间的良性循环,才是云原生这个词的本质,我把他称为云原生怪圈。

       

       

 

虽然按照这个顺序来讲,你会感觉体系有点乱,但是才是最落地的演进路径。而沿着这个演进路径发展,你才能感受到“云原生”三个字的准确含义。


很多企业应用层服务化或者微服务化,而技术底座没有跟上,从而系统陷入混乱,没日没夜加班,却怪服务化不好,另外一些企业花了大价钱卖了一个技术底座平台,但是应用层没有跟上,无法促进业务发展,嫌技术底座白花了钱,这两个误区都在于没有沿着这个怪圈逐渐演进。


为了解决体系混乱的问题,所以在展开落地篇之前,先来一个总论,整体梳理一下。



对于每一个落地的步骤,我们要经常问自己下面几个问题,我们成为四项基本问题吧:

  • 遇到什么样的问题?

  • 应该采取什么样的技术解决这个问题?如何解决这个问题的?

  • 这个技术的实现有很多种,应该如何选型?

  • 使用这个技术有没有最佳实践,能不能形成企业的相关规范?


整个落地的演进过程要有一个起点:

  • 在应用层,是一个单体应用,主要包含Online服务,他是对外提供服务的,Offline服务,他是一些定时任务的,MS服务,他是一些后台服务,这基本是一个单体应用,因为对外服务是Online,接下来的拆分也是围绕这个服务展开。

  • 对于数据库,使用的是Oracle,部署在物理机上

  • 在基础实施层,用的是Vmware虚拟化

  • 部署上线方式是脚本化

 

接下来,我们要开始演进了。

 

就像前面我们讲过,构建中台的企业都是有一定积累的企业,而非创业企业,因而不可能没有任何计划的的盲人摸象,这是很多企业的管理层不允许的。所以在动手之前,要有一个总的地图,就是规划,当然真正云原生演进的时候,我们不建议使用瀑布模型,而是迭代模型,但是迭代模型不代表漫无目的的迭代,而是地图要在心中,所以落地的第一个阶段是规划。

 

第一:规划——在架构委员会领导下的梳理与规划


首先,组织架构先行:成立架构师组。哪怕人很少,只有两三个人,但是这个组织一定要有,这是将来的军机处,是架构委员会的发起者,是横向拉通各个组,并落地规范与最佳实践的负责人。


有了人以后,接下来,我们应该从业务架构出发:进行业务流程和领域梳理。在云原生怪圈的循环中,我建议从业务层出发,因为IT是为业务服务的,只有业务方的需求,才是真正应该服务和花钱建设的地方。



(步骤1) 从1到2:领域驱动建模


从标题你可以看出,这是按照领域驱动设计的方式来进行规划的。


这里很多技术人员都会犯的错误是,从数据库出发,看数据库结构如何设计的,按照数据库最容易拆分的方式进行拆分。这样是不对的,没有站在业务的角度去考虑问题。应该借鉴领域驱动设计的思路,从业务流程的梳理和业务领域的划分出发,来划分不同的服务,虽然最后映射到数据库可能会拆分的比较难受,但是方向是对的,只有这样才能适应未来业务的快速变化。

 

我个人认为,方向比手段要重要,方向对,当前痛一点没什么,但是当前不痛,方向错了,还是解决不了问题。


首先,我们要做的是梳理业务流程,通过这个流程,可以了解业务运行的逻辑,使得技术人员对于业务模式有所理解。

 

这里主要梳理的是电商业务,也许你对电商业务不是非常感兴趣,但是仍然建议你把这一节看完。因为后面在架构设计的部分,都要基于对于业务流程的理解。其实作为一个架构师,越是到后期,越是要距离业务要近,而不仅仅是单点做一部分的技术。电商平台是一个典型的应用云原生架构的案例。虽然你当前所在的行业。有可能是金融,制造,或者零售。对于方法论来讲,你总能从电商平台的流程和业务模式中,找到类似的部分。他山之石,可以攻玉。

 

下面是电商平台的一个典型的业务流程图。



具体的业务流程,我们另外解析,这里不赘述。


接下来就是,划分业务领域。梳理好了业务流程,我们就可以根据他来划分业务领域。这里不必严格按照DDD的图,为了方便,我这里用了脑图。



另外,对于每一个服务,我都起了名字,这里先不用管它,后面自然有用。

 

在实践中,你在这个阶段可能没必要划分的这么细。这些服务都是在后期的逐渐拆分过程中演进出来的。



那接下来后台技术部门不应该闷头开始就按这个拆了?其实不是的!

 

传统的领域驱动设计是瀑布式的模型,经过长时间的闭门讨论,贴纸条,最终输出各种架构图,但是当落地的时候,发现情况变了,因为领域知识从业务部门到技术部门的传递一定有信息的丢失,这也是DDD落地被诟病的地方,就是业务方规划的时候是这样说的,落地来需求的时候,却是另外一种说法,导致根据DDD落地好的领域,接需求接的更加困难了。

 

所以一个更加落地的方式是,随着新需求的不断到来,渐进的进行拆分,而变化多,复用性是两大考虑要素。

 

所以赵本山说,不看广告,看疗效。对于服务拆分,DDD是一个完整的地图,但是具体怎么走,要不要调整,需要随着新需求的不断到来,渐进的进行拆分,DDD领域设计的时候,业务方会说不清,但是真的需求来的时候,却是实实在在的,甚至接口和原型都能做出来跟业务看。

 

这么说有点虚,我们举个现实的例子。例如按照领域的划分,对于电商业务来讲,一个单体的电商服务,应该拆分成下面这些服务。

 

             

 

需求到来的时候,技术部门是能感受到上一篇文章讲过的架构耦合导致的两个现象:

  • 耦合现象一:你改代码,你要上线,要我配合

  • 耦合现象二:明明有某个功能,却拿不出来

 

第一个现象就是变化多,在业务的某个阶段,有的领域的确比其他的领域有更多的变化,如果耦合在一起,上线,稳定性都会相互影响。例如图中,供应链越来越多,活动方式越来越多,物流越来越多,如果都耦合在Online里面,每对接一家物流公司,都会影响下单,那太恐怖了。

 

第二个现象就是可复用,例如用户中心和认证中心,根本整个公司应该只有一套。

 

在《重构:改善代码的既有设计》有一个三次法则——事不过三,三则重构。

 

             

 

 

 

这个原则也可以用作服务化上,也即当物流模块的负责人发现自己接到第三家物流公司的时候,应该就考虑要从原来的单体应用中拆分出来了。另外就是,当有一个功能,领导或者业务方发现明明有,还需要再做一遍,这种现象出现第三次的时候,就应该拆分出来作为一个独立的服务了。

 

这种根据业务需求逐渐拆分的过程,会使得系统的修改一定是能够帮助到业务方的,同时系统处在一种可控的状态,随着工具链,流程、团队、员工能力的增强慢慢匹配到服务化的状态。

 

那你可能会问,如果有个系统,里面的代码已经垃圾的一塌糊涂,我都看不下去了,但是暂时没有新需求进来,那应不应该拆分呢?

 

不!没有需求不拆!再烂也不拆!我们不是要解决所有的腐化问题,别按DDD的理想情况来。

 

至此,理论的划分基本就结束了,接下来,咱们就要动代码啦!


第二:试点——选一个项目试点,汲取经验,培养团队,建立规范


(步骤2) 从1到2:选取试点业务进行拆分


我们来选择一个领域将他拆分出来,我们就选择最核心的交易领域吧。

 

               

在上面这个庞大的单体应用中,我们将订单拆分出来,需要考虑以下几个事情:

  • 在诸多的功能中,将属于订单的功能梳理出来

  • 梳理订单和其他模块之间的关系,从而知道将来会和哪些模块进行相互调用

  • 将订单模块中的不同功能也进行划分,虽然目前不用拆分,为了将来拆分做准备

 

第一件事情,我们从上面的图中可以看出,黄色底色的就是属于订单的功能。

 

第二件事情,我们需要梳理一个关系图,如下所示。

            

第三件事情,将订单内部的功能也划分一下,因为将来可能会因为性能问题,进一步的划分。

 

              


接下来马上应该找拆分了,先别忙,你会不会拆出一堆Bug来,让原来单体应用玩儿挺好的,后来Bug成堆呢?这也是经常服务化被诟病的地方,Bug更多更不稳定。

 

所以首先要有持续集成,这是云原生架构的基石。


(步骤3) 从1到2:持续集成平台建设



持续集成就是制定一系列流程,或者一个系列规则,将需要在一起的各个层次规范起来,方便大家在一起,强迫大家在一起。 

 

接下来,我们一起来搭建一个持续集成的系统。

 

             

 上面的这幅图呢,是一个持续集成的总体流程图,里面包含非常多的工具,这些工具呢,有非常多的选型。下面的这个脑图,就总结了持续集成中所常用到的主流工具。你可以根据自己公司的情况。来选择合适的工具。

 

             

 

系统的搭建只是其中一部分,要做好持续集成,还需要有规范,还需要配合敏捷开发的流程。


持续集成的规范都有哪些呢?


  • 工程名规范:这个名称非常关键,以后在公司内部所有的系统中,只要看到这个名称,无论是开发,运维,发布人员,QA任何角色,在持续集成平台,云平台,容器平台,微服务平台等任何平台,都以这个名称为准绳,这样所有人看到名称,马上就知道这个工程什么功能以及应该如何操作他,如果是一个核心交易的前台工程,就应该小心一点,如果是一个后台的管理系统,则小的功能白天也可以发布。

  • 代码结构规范:代码结构规范希望达到的效果是所有人打开一份代码,都能看到熟悉的结构,以及有大概的思路如何入手,这在快速迭代的场景下很重要,因为人员也可能在不同的团队频繁的调动。

  • 代码设计规范:包括命名规范,例如package, class, interface,变量的命名;包括注释规范,我们要根据注释生成文档,这在注册中心和知识库还会提到;资源管理规范,例如对于文件,线程,网络,数据库连接等的使用;异常管理规范,如何捕捉异常和处理异常;日志规范,日志的分级,敏感信息过滤,格式规约;多线程规范,并发,加锁,线程安全;数据库操作规范;编码规范,例如方法长度,类长度,数据模型定义,相等判断,异常抛出等;

  • 代码提交规范提供注释规范,冲突处理规范,warning处理规范,格式化代码规范等。

  • 单元测试规范:单元测试覆盖率,有效性,Mock规范。


(步骤4) 从2到10:构建注册中心与知识库



我们构建了持续集成的系统,规范,流程,还有一个问题没有解决。

 

一旦订单中心从电商的单体应用中拆分出去了,这就存在当订单中心和其他业务相互调用的时候,如何知道订单中心在哪里的问题。我们假设原来的单体应用为Online,而新的订单中心称为Order。



因而这里我们需要配备一个工具链,那就是注册中心。