说明:本文为戴姆勒大中华区架构师朱傲老师在 2020 DevOps 线上峰会的分享整理而成。
作者简介: 朱傲,戴姆勒大中华区 架构师。
一、应用现状
我的工作是做应用架构设计,把企业架构向开源演进。我今天的话题是去年将公司的核心系统-客户数据管理的系统这一个传统的应用进行云原生改造的实践,那跟大家分享我们做实践过程的经验和一些思考。
我司是一家非常典型的工业制造公司,不像是阿里、腾讯大的互联网公司,在它的IT里面往往会存在大量遗留的系统,并且是以很多商业产品为基础构建。那今天谈的系统就是基于IBM的商业产品进行的二次开发。
为什么说它是传统应用,相信大家做 DevOps 转型都会面临这个问题,大家都在企业从事技术工作,企业经历信息化的技术发展,已经形成了大量的传统应用。
那目前随着云以及包括 Cloud-Native 成为主流,大家都想把传统应用搬到云上,在我们公司也是一样,我们现在目前对所有的项目都期望是一个云优先,对所有新项目我们默认采用上云,基于云构建,基于开源软件研发。
虽然新项目直接就在云上构建了,但老旧系统也是需要搬上云,现在已经随着数字化普及程度越来越高,这样的改造已经无可避免,我们必须进到项目里面,进到每一个应用里面,将他们逐步搬上云。
今天分享的项目就是这样,我先简单说一下项目的背景,这个系统是管理所有的终端用户的客户信息,包括线上线下,这个里面会跟两类系统区分,一类是IAM,客户的统一认证登陆;另外是CRM,客户关系管理系统。我们这个客户管理系统听起来也比较纯粹,就是客户信息数据管理。
这个系统上基本被我们内部所有的系统都引用,都有集成,这个系统是比较核心的系统,特别是现在大家都在关注用户增长的情况下,这里面的用户有一些车主信息都是一些比较高质量的客户信息,所以我们动它的时候非常小心,不能带来数据质量下降和数据错误,因为有可能引发客户投诉。
这里面大家可以看到一个传统的应用,我在这里面展现了一个架构和传统应用的特点,大家待会听完就会发现传统应用的痛点,跟大家非常相似。
简单说一下架构,部署在一台VM里面,当外部的请求过来,里面会使用IIB这样的消息队列,然后会对请求进行校验,会使用到IBM的IIS,不是微软的IIS。另外是主数据管理,用到IBM产品,当数据保存到数据库之前会进行排重。同样我们是线上线下客户数据,这是线上部分。
线下是后期构建,所以线上是采用JAVA的技术栈,同时用本地数据库,个人上传的个人资料信息会加密存储在本地磁盘。所以整个一套架构下来大家会清晰我们是单体的,没有什么太多的业务的划分、业务的识别在这里面。
在这里面基本上哪怕我们现在每个月的流量在三千万,这个服务的请求数三千万,但是这个数量级肯定跟互联网没法比,但是相对在传统企业里面,每月流量请求有三千万,我觉得已经是不小的数据体量,那这样的系统我们一直用一台VM顶着,顶了三年。
我相信传统IT基础设施大家都清楚,我们会要打patch,每次这样只能停机等待,等结束之后我们才能真正对外提供服务使用,大家可以想象当我们打patch的时候,我们的客户信息会传到哪?当你给想要买车询价的时候,这些客户信息会存到这个系统,当你登陆官网的时候也需要用到这个客户信息,那么当你停机的时候这些都是不可用的,所以影响挺大的。
同样因为每次部署,因为要停机,我们每次都是晚上干这个事,因为卖车不是跟互联网业务一样没日没夜工作,系统上面到晚上的时候会有一个使用的低谷,所以我们一般在重新部署的时候都会选择在半夜进行,可能是通行的做法。
那CI/CD不用说了,我们基本上不用想了,我们的代码全部都是上传到商业产品里面去,在商业产品部署,所以对我们来说我们基本没办法做自动化部署,连代码编译我们在本地都没有。
另外谈到扩展,因为商业产品的原因,在中间整个使用费用,基本是按照CPU的核数来算,也就是我们要扩展,要按这个来算费用。今天发现我们传统系统的改造,软件成本非常巨大,往往是改造的重点,甚至是我们能够改造它的一个动力,一个非常重要的动力,我们能够从软件的license费用省出不少钱完成后面的改造作业。
接下来是商业产品的现状,现在运行的稳定性挺好的,而且该商业产品这个生态并没有死掉,活得很好,但是我们还是考虑自身的因素,我们希望把整套东西搬上云,这些组件搬上去,工作量会非常大,那我们怎么做这件事?
大家都在说传统运用的时候,其实往往是带着批评的态度。但是如果我们不去思考传统应用给我们带来什么问题以及我们怎么解决为什么要解决,那很有可能会给我带来额外的问题,新的问题会引发。
我们往往谈的时候是说我们的传统应用性能不好,但是事实上我们分析后发现刚才的应用,难以替换的一个大的点就是在这个数据的去重、排重性能上很好,如果贸然替掉,这个不是通过我们横向的伸缩就能够解决的性能问题,所以说这个时候我们就要思考,你这个传统应用到底对你来说意味着什么。
所以传统应用其实性能很好,并且在某些程度上面,某些地方是有优势的,虽然这个应用性能很好,但是它的容量已经顶不住了,待会会讲容量的要求。
另外传统应用很多是基于商业产品,它的健壮性,比这些微服务的健壮性好很多,因为这些商业产品经历过很多迭代打磨,我们经常是快糙猛的上线,你的很多质量保证和日常处理不到位,这个时候健壮性远远赶不上传统的应用。
对我们来说它的健壮性确实很好,这就对我们提出了要求,当我们转换成Cloud Native的时候我们是否达到了相同的健壮性。传统应用其实功能非常强大,在专业领域、业务领域里面有常年的积累,有很多业务专家总结出来业务功能,能够帮助我们把问题快速完成,只不过不能满足我们新的功能里面个性化需求,所以传统应用你要明白能用它什么,不能用它什么。
那这里面我们刚才提到这些多好处,传统应用从商业产品来说还是有很大价值的,这是一个现在对当前的传统应用的价值分析和一些想法,就是我们在做的时候它是达到了一定的要求,但是没满足未来的期望,那我们再做迁移上云的时候,已经完成了,已经做到的事情我们不能退回,有可能是越做越差的,我们要非常小心做这些事情。
二、改造目标
那接下来继续看看,把系统打开剖析一下,看看我们改造的目标是什么。因为今天是我第一次通过线上的方式来跟大家分享我的话题,可能缺少了现场的互动,希望大家在留言区积极留言,后面话题结束之后我们可以一起探讨大家感兴趣的问题,有任何问题欢迎大家随时提问,我如果看到会给大家进行解答。
那继续看改造目标,其实说上云的时候大家首先想到我能伸缩了,这个很重要,挺好的,出了问题就会有Backup,大家都是看到了这些上云的好处。但是当你跑去跟业务讲这些事情的时候,很多业务会跟你说我没有钱,上云虽然听起来挺好的,但是我看到了你们做的其他上云的应用也没有做成什么样子,该出问题的时候还是一样出问题,并不是上云就能解决质量不高的问题.
所以大家对于上云这件事情,当在公司里面要去寻求资源支持的时候还是会碰到很多困难。其实业务人员的基本想法和感受就是上云听起来挺好,但是我没有钱,这个钱投资值不值得,不确定。
这个时候就要想想我们这个系统为什么要上云,我们提出的原因是什么。刚才说这个系统是客户管理系统,在现阶段这个系统是在2016年上线的,PPT中数据是2017年,当上线的时候客户数据主要关注线下客户,就是通过打电话进来的客户,通过在经销商店里面留的个人信息过来的客户,所以起初更多是有大量线下客户数据,是在一百多万。
随着两年的发展,目前我们线下的客户数据大概在三百到四百万,但是还有一个不能忽视的业务发展趋势,是有大量的线上客户,这两个是不一样的,大家可以看到架构数据里面我们是有两个数据库隔开的,这里面有一些业务需求的考量。
但是大家会发现我们线上的客户数据是快速增长的,它的容量要远远大于线下的,并且这个业务在未来我们的策略里面也是线下用户线上化,引流到线上去,让客户能够享受我们的其他的增值型服务,不仅仅是一次性购车之后就中断了客户的连接,后面的数字化的服务都希望能够跟上,这是未来我们在业务上面的期望。
那在客户数据上的容量层面,我们预估会在未来两年内会增长一倍,这个时候现有系统里面的单机性能不错,需要再买一个license,再把现在的软件成本翻一番,支撑容量增长。那这个增长一倍,成本增加一倍,大概一年两三百万,数额不少。
所以我们希望把涨的这部分钱用来对系统进行改造,让系统容量能够提升上来,同时能够真正把对以后的拓展不是再靠第二个三百万、第三个三百万license扩展,因为当你数字化程度越来越高,后面的增长幅度是非常惊人的。
所以这是我们的业务目标,当然对我们分析业务目标的时候刚才一直讲,业务里面有一个潜台词,就是我不增加额外的成本,所以我们整个改造过程是在新增的三百万成本缩减下去完成的。
同时业务还有其它考量,做市场推广活动进行车展和市场营销活动的时候,我们短时间的业务访问量,是有七到八倍增长,所以我们要预计短期内有三到十倍的业务高峰能够扛住,所以这是我们希望改造的目标。
那说完这些,大家可能会开始想这些业务目标能够达成。其实在没有预研之前,我们也不完全保证。在技术选择方面,从公司层面也是有要求的。譬如之前提到的云优先及开源。
所以结合项目情况,我们也拟定了技术目标。第一个目标我们希望拥抱开源能够把商业产品去掉,确保后续的业务增长不会被锁定。第二个目标是云原生打造。我们去掉商业产品是省钱,然后用省出来的钱上云,上云是一个技术手段了,我们希望能够做云原生改造,搬到云上,支撑后面业务容量的增长,包括低成本的容量增长上去。
那我们想要让我们在云上的服务的质量不要比商业产品更差,那 DevOps 就是不得不要的,公司内就是默认必须做这个事。那REST API和微服务都是我们这次在技术层面看到的技术需要。同时为了让IT跟业务结合。我们认为需要把API改成REST以及需要进行微服务改造。
这是我们的改造目标,大家会看到这跟 Cloud Native 里面的实践很相似,Cloud Native是一个技术的集合,我们要非常明确知道这个技术能给我们带来什么价值,我们要应用这些技术,而不仅仅是我需要做云原生,也不能一鼓脑就把这五条实践一次性放到改造当中去,这个改造成本会非常高,并且你的投入回报能不能达到要求也是一个问题。
所以大家要理解云原生里面的技术实践是否能帮你解决什么问题,而不是一上来就要用,包括我们是不是一定要做微服务改造,因为之前我也做过其他上云的改造,有一些确实做得比较简单,没有做微服务,这里面给大家分享的是运用综合性手段的,所以这是大家在实际落地中需要做考量和考核的,后面也会跟大家分享我是怎么思考的。
三、改造方案
那就来具体看一下改造方案,对业务来说这些改造经历了从十月份到十二月份再到今年的十月份进行第二期改造,业务人员很担心,他们就希望别把系统搞挂了,别出问题。那在制定整个Cloud Native 改造的时候我们是按照下面五个步骤去分析和思考系统改造的价值。
首先第一个我们要了解系统业务,构建领域模型。了解业务很笼统,可以跟他谈谈业务流程,谈谈用户旅程,包括随便聊天,做个采访了解业务。但是对我们做架构的人来说,当你了解完业务之后,你要构建出来这样的领域模型,帮助整个团队对业务的边界范围以及核心价值进行梳理。
大家能看到我的右上角是梳理出来的领域模型,在这里面能看到该系统的核心数据是什么。核心的数据是线下用户和线上用户,线下用户有什么比较重要?为什么线下数据体量整个系统里面条目数达到十亿,为什么百万的数据量条目数这么多?
刚才说两三百万的用户是形成购买的用户,那我们有大量的潜客和注册客户的信息在这里面,所以这里面你会发现是整个客户全生命周期的管理,这个时候我们有没有把这样的模型再识别出来,构建出来。这个东西不仅仅是为了技术,也是帮助业务去理解我们这个系统,我们这块业务能做什么样的事情,在做什么样的事情。
后面会发现我们会用领域模型做应用架构,所以大家了解完业务之后一定要有产出,产出就是领域模型,只有把领域模型画出来,才可以说对这个系统有了自己的理解。
接下来我们做系统分析,整个架构需要进行梳理,你的集成关系,有多少系统的集成,用什么技术栈。还有每个技术组件里面承担什么职能,做什么事,你是否心理清楚,待会我会跟大家讲我们的技术组件是怎么看待它的,怎么梳理的,它对我们的价值是什么,未来当我们想要完成扩展之后,以及我们要在约束下面完成扩展的时候我们是怎么做的。
第三步就是性能分析和容量预估,业务的核心目标就是要把容量翻一番,所以这里面我们一定要去计算说我们在机房部署应用以及包括在什么样的计算资源下云的计算资源下能够达到甚至容量翻一番的目标,这个是要记住的,要一点计算出来的,只有这个计算之后你才能知道自己的成本,以及包括你搬上去之后,是不是真的能够做到,你必须要有这样的考虑,包括以后选时的时候,在活动的时候,集中一段时间有三倍到四倍之后,你到时候怎么处理,这都是我们需要做的。
第四个成本分布,这个其实是有点意思,因为我们这里面有一个比较大的约束就是钱,那我们希望马上用新增license的费用去覆盖支撑整个系统的改造,所以这里面对成本做了细致分析。
最后是一个识别约束,就是前面我们系统整体的业务、架构、性能做了分析梳理之后我们要知道其实有很多方式方法可以完成,那你选择什么方式方法,你要知道你有哪些约束。
这里面可以看到核心的有三个约束,第一个就是我们有大量的外围系统,这意味着什么?就是我们的系统在去跟外界沟通交互的时候,这些上下游我们要逐步替代,让它做修改,都是小小的对外的调整都会引发上下游的调整,这是我们要时刻牢记,就是我们的改造工作要减少对上下游的影响。
第二个约束就是我们的商业产品,这个商业产品也是一个黑盒,有人问如果是一个闭源产品怎么办?那我们这个系统的核心部分就是闭源的,但是对我们还算比较好的就是它很多上面的二次开发、编码还是我们自己人在上面做,所以这里面怎么做的这些业务大家是很清楚的。
当然我也改造过一些系统是完全闭源,闭源到连数据库都是自己的,是非常小众的数据库。所以大家在里面会有这些约束,我们知道说像这些产品IBM是在支撑使用的,它也会有一些它的上云的方案和规划,所以这些约束大家要去识别和去看。还有第三个约束就是反复强调的钱,这个不多说了。
当我们做完一系列评估之后我们给出的方案是什么,其实大家可以参考一些业界总结的思路,总体的上云思路上面大家可以参考AWS“6个R”的模式,大概就把我们整个上云改造的总体手段分成六种,每个手段都有适应不同的场景。
这个是我之前先了解的基本思路,就是我们会用这些手段,但是我们并不会照搬。我们这里分了三步走,第一是去商业化,第二是服务化上云,第三步是开放API。
这里面第一步去商业化的目的,我们会把很多无用的组件去掉,做了成本分析之后我们发现有些组件不需要,可以省掉,那之后就可以拿 License 省下的钱做下一步的工作,并且是直接覆盖了人工成本。
我们也会用一些开源组件,外部的服务替换现有的功能,这是在最大化的程度上先节省出来一部分钱,再做这些事,先把我们的钱挣到,再做服务化改造,这个时候就是一个重头戏了,前面做了业务架构的分析,构建领域模型.
其实我们针对自身的业务应该建设哪些微服务已经清楚,同时我们也知道拆成微服务之后业务会带来什么价值,这个时候我们就可以谈我们为什么要做微服务改造,中间同时我们就会开始做性能提升,其实当大家开始用微服务改造就是上面6R里面的重构手段。
最后就是开放API,在整个公司内部我们需要这个核心系统开放API,告诉他集成非常多,那集成的方式是否足够流畅,就会对上下游的依赖包括稳定性也有要求,对上下游的使用方式具有很大的影响,所以第三步要求更高。
那我们接下来具体细看一下这个步骤,第一步我们说去商业化,这里面说做了件事,第一步把IIB去掉,IIS也去掉,MDM重写,DB2也换成了Oracle,这些是结论,那我们为什么能够去掉IIB,目前的架构大家可以发现,IIB承载的目的就是只做了一件事,就是做了接口的转换,数据传输的转换,相当于这里面不是一个真正的消息队列,并不需要消息队列做这个组件,请求直接到达下面的MDM和IIS这个组件都可以,因为往往是有异步任务要处理时才用到消息队列,但是这个消息队列放在内部的组件集成,并且是同步操作.
所以大家会发现IIB在这里非常鸡肋,后面评估之后发现直接去掉就可以,唯一要做的就是对外API和对内API的适配。不知道当时设计这个组件的原因,但是在我们看来这个组件没有任何的价值,技术和业务都没有价值。
再看后面的IIS,也说要替换掉,为什么要替换?也是遵循刚才的思路,说这个组件的职能是什么为什么用这个组件?发现这个组件做的就是对请求参数进行校验,当客户输入个人信息的时候进行交验,因为我们需要保持一个高质量才能对下游系统提供数据保持价值,所以对提供的数据进行了清洗。
本身这个产品有很丰富的数据清理功能组件,我们就用了三到四个小组件,更多的逻辑还是自己在上面的二次开发,这个就意味着IIS的价值在我们这个系统里面并非无可取代,其中一个地址校验功能我们采用了SaaS服务进行替代。你会发现核心看这个技术组件到底有什么价值。
最后一个比较核心的就是MDM,这个组件最核心的业务功能就是帮我们做数据查重,那我们能不能替换?其实MDM重写目前还在进行,那它有一个性能优势,它每天做几百万数据之间的查重和合并的时候,它的性能是不错的。我们觉得还可控的原因是这里面所有的查重排除的逻辑和规则都是由我们自己定义,不是由该商业组件提供。这里面有将近六千多条规则,都是我们一点点放进去的,业务分析人员有六千多条规则注明怎么做,也是用JAVA实现的,所以我们有信心重写MDM,核心就是我们后面能不能在性能上达标。当我们确定方案之后,我们就开始做POC了,看看怎么完成这件事情。
最后的DB2,这个是替换成Oracle,主要是DB2贵一些,所以现在暂时换成Oracle,其实我们现在还是想要替换到开源数据库,但目前来说因为我们改造项目已经不少了,所以步子还是迈小一点,暂时替换成Oracle,后续还会再调整。
这个就是去商业化,这里面非常大的核心就是大家要去想,我们在碰到商业产品的时候,最大的难点就是你对这个商业产品上面构建出来的系统业务知识是否足够,只要足够,后面可以通过很多不同的手段去完成对它的改造,如果缺乏这样的业务知识,这才是真正最大的问题。
刚才说的闭源系统就是存在这个问题,业务知识都是缺失的,后来我们都是先学了业务知识的,所以工作量很大。当然也有不适合的,我们是一个卖车的系统,对于非业务系统可能就不需要学习那个知识,没有那么大的价值,但是对我们来说必须掌握核心业务系统,如果自己没有掌握,其他的厂商会复制。
这是我们在商业化的时候我们的案例,我也相信每个场景有千差万别,有的会更困难,有的简单。
但是核心第一要有业务知识,第二要知道技术的核心价值是什么,技术组件的核心价值是否能够用其他的方式解决和替换,次重要的其实可以不需要,这里面我们也抛弃了很多其他的组件,都没有画出来,就是买这套东西的时候带来很多组件,我们直接抛弃了。
这是刚才说的商业组件,接下来就是服务化上云。那服务化大家看到我前面做的领域模型,领域模型这个时候就转换成微服务的设计,这里面我分享一个我们做这个业务微服务的原因是他们在做他们的投资组合管理,管他们的钱怎么花之后,通过微服务就知道他们钱花在哪里。
以前不管是做线下线上融合,业务的综合,数据的清洗,大家都是笼统说我要提升我的客户数据质量,就是这样的话,每年几百万钱扔进去,但是如果把服务分开,我做的其实就是,比如说去年投资 membership 服务,就把多个会员体系进行了整合。
今年的投资是在online customer和offline customer两个服务,做线下线上融合,这些大家发现投在不同的业务里面你的投资组合就非常清晰了,这是我们做的一个工作。
后面开放API,这个是非常明确的,我们看准了这个方向之后,我们认为需要往API化方向走,我们提的要求就是在所有的服务当改造的过程都要暴露出API,API是在设计、监控以及整个的生命周期都有要求,并且还有成熟度模型,推动团队把这些做起来。
四、云原生改造总结
最后我做点总结,这里面其实我还没有给大家讲的就是CI/CD,因为时间有点长了,我快速讲一下,我们稍微回顾一下刚才说的这个方案。
大家发现前面第一个就是要理解业务,识别技术组件的价值,每个技术组件对你来说意味着什么,就在这个改造的过程中,当我说要把IIB干掉之后,交付团队开始给出云上的架构,因为我要说做微服务,上来先把 Eureka 挂上来了,我就问它这个对我们意味着什么,他说注册发现,你的微服务不需要注册发现吗?
我说我不需要,他就愣了,说为什么不需要?因为在我们整个环境下,API网关就已经完成了服务发现的工作,每一个微服务都是独立发布自己的API出去,大家通过API集成,我们把每一个微服务当成独立的业务,所以不需要中心化的组件来去控制它。
我们服务的治理其实是一个比较落后的方式在完成的,我们不需要实时动态增加新服务,每个服务新增的周期比较长,不会在分钟级,这个时候不需要这样的组件。所以大家要知道你每个技术组件是干什么的,这个是要想清楚,能不能带来价值,这是要提醒大家的。
第二采用6R的方式,我们不仅仅满足于Rehost,我们要做深入的探索,看看综合应用六种替换的手法。
云原生改造的时候技术非常多,包括最基本的12因子,大家上云的时候还是要坚持一下12因子,除此之外我们作为技术人员还是要考虑一下上云要做云原生的时候,其他的改造是否跟上了,容器化肯定会做,但是不是简单Rehost,其他的技术实践是否有价值,值得我们去实施。
最后一个就是前面没有跟大家分享的团队工程实践能力的培养,这个前面一直提到的就是你搬上云的时候会不会退步,懂不懂怎么小步把能力验证上线,大家也可以看到我们第二步才做微服务改造,第一步是把组件去掉,首要是钱的原因,其次也需要在第一阶段检验检验培养团队的工程实践能力,看接口测试是否需要补上,有没有这个能力去把这些工具应用起来,使用起来,这都是我们在前面第一个阶段的时候开始做的事情。
这是一个完整的实践案例。我们希望能够搬上云,不但要享受到云的好处,同时改造又不能把质量拉低下来。