加载中…
正文 字体大小:

从技术层面看如何解耦

(2014-05-01 20:39:42)
标签:

持续集成

持续交付

组织架构解耦

插件微服务

自组织

分类: IT相关

在Qcon的大会上,腾讯的电脑管家项目经理来说明是如何把版本周期从2-3个月一个版本到1天2个版本的过程,他们分4个阶段进行了介绍,再结合银行的系统来看如何能够把一个系统解耦到可以变得更加快速的发布版本和支持业务尝试。

阶段一:初始状态,这个状态和我们当前银行的情况差不多。

对于电脑管家这个软件,在100多人的开发队伍中,分了许多“特性小组”,每次版本有2周的开发时间,每个小组由1周的单元集成测试时间,然后一起合并版本,理论上2周的归并后测试时间,最后用3天的封板时间,进行上线准备。

但在这个状态下,通常无法做到3个月能够上一个版本,因为代码合并所需的时间远比想象中长,合并测试也痛苦很多,互相修改了对方的代码和功能的事情经常发生。以至于他们使用按责任罚款的方法,导致开发人员再提交代码的时候手抖心紧。

阶段二:技术解耦,这个通过迭代开发,可以支持到2周一个版本。

阶段一的核心问题,在于每个“特性小组”所开发的功能,依赖的代码是和其他“特性小组”的代码重叠的。而且软件必须整体打包编译,一旦有一行代码编译不过去,所有人的代码都无法发布。阶段二就是从技术层面解决这个问题。首先设计底层框架,把整个系统全部插件化。定义明确的功能间的接口,并且用系统内标准接入隔离各个功能,在框架内确保每个模块可以单独以插件方式下发,技术层面,尽量降低发布代码的依赖性。简单来说,就是把原来一个系统中的各个功能,分拆成多个系统,多个系统可以在一个容器内运行,容器是底层的,容器会负责用户信息,负责一些公共的通讯,一些事务管理。每个功能是部署在容器上的插件。每个插件的代码独立。不会互相依赖打包。

在这个阶段,清晰接口后,编译就不会出现代码级的依赖,整个软件的功能测试以回归为主,自己模块内的测试自己搞定。从技术角度缩短了归并带来的问题。提高了开发效率。单个版本的周期,不考虑迭代,还是在4-5周。

阶段三:组织架构解耦:通过迭代开发,还是2周一个版本。

这个阶段,就是把原先按开发,测试,SA这样的流程架构,修改为特性小组一条龙,不再有独立的测试,SA团队,打破本位主义。这样是提升了效率,但目前还面临一个问题,就是仍然是一个软件一个版本。

阶段四:发布解耦:通过建立模块版本配置表,允许单独模块单独发布,单独回滚。支持到1天2个版本。

这个就是持续构建,持续交付的最终得目的,技术和运维层面把每个模块彻底可独立发布配置,接口稳定后,这样就允许小改动快发布,大改动,慢发布。避免所有的改动都要找版本。这个需要自动发布,灰度发布,自动化运维,自动化监控很多底层的技术层面的支持。

 

现在对比银行的系统,就拿一个我最熟悉的BOCP系统来看。从银行整体来说,我们在零售运营团队上,也是差不多300多人的开发规模。我们也已经拆分了很多个子系统。但是从单个系统来说,我们在每周都有版本的时候运维和开发的压力非常大,而且的确因为Bug,很多时候我们保持了一周一个版本,但主动优化的,正常是一个月一个版本。但问题是业务总对我们交付效率不够满意。

从版本周期来说,也许我们没有那么糟,不过效率才是最主要的衡量标准。目前有些系统功能已经没有人敢去修改代码了。一个页面上就有几千行代码。里面有支持很多个产品和很多个不同的业务逻辑。

1. 技术框架层面,我们还是少做了一些事情。我们需要在J2EE容器上再有一个自己的容器,也就是我们之前说的BOCPSDK来解决底层问题,PAFA本身横向层次太重了,竖向支持又太轻了,而我们最初没有规划好BOCPSDK,只是抽取了公共技术代码,没有从容器的角度上来让应用可以单独发布,单独部署。没有一个系统内的ServiceBus可以隔离各个模块之间的调用依赖。当然,我们也做了不少的对得事情,只是没有彻底下去。其实完全可以通过一些设计模式,动态加载类的方式,把模块放在一个清晰接口内的范围内

2. 前端UI,没有和业务逻辑代码分离,这是个致命的问题。前端复杂的是JS,而互联网时代,JS只会越来越复杂,所以需要把业务逻辑的JS通过框架,一样和展示分离,并建立页面拼接框架,确保一个页面可以获取多个系统的数据,而不是现在这样的页面一定来自于3000行绑死的代码,一个页面的数据,展示,控制逻辑,应该可以分别来自多个系统,展示层负责组合,但只管理展示组合。逻辑要保持独立性

3. 数据层面,必须分离我们原本从业务建模所认为的一些对象,宁可多一些表,简单来说,如果业务流程在第一个步骤,只能产生10个字段,可能这10个字段就是这个表的所有了。假设在第二个步骤会生成后5个字段,那么这5个字段可能和步骤二一起,可以看作,是属于第二个系统的。解耦数据,会带来后面查询效率的问题,但是如果我们把视图和数据同步技术解决了,在交易系统中,我们拆分非常细,在批量和数据系统中,我们再把数据整合起来,按需获取自己所需要的数据,就是要在最初明确每个垂直模块的边界。把耦合降到最低。不然随着系统的自然增长,只会重新陷入最初的境地

4. 清晰的接口,需要能够做到Mock测试是可靠的。所有的测试,都应该保证80%的自动化测试率。这样就不需要必须编译在一起测试所有功能。自容器的功能,要确保发布是可以独立的,不能再每次都是Ear包发布,这种发布模式过于庞大,而且不利于故障重启。必须按文件发布,或者按Jar包,按War包发布。所有的发布,必须考虑自动化的方式。这里最复杂的不再于Java代码,而在于DB,测试是有修复移交,而生产发布是一次的,这里要通过规范和工具实现自动化。当然不排除可以有20%的情况必须手工。但如果发布都是自动化,操作风险和测试的风险都降低很多

 

其实从一开始,我们选择开放平台,我们就已经在松耦合的路上了,我们的子系统数量众多,并且清晰的定义了发布单元和子系统之间的关系,但是我们在技术框架上,的确停滞了太久没有进步。我们在2001年开始走开放平台,但是10多年没有一个真正落地的系统间调用框架,也没有一个系统内模块划分框架,即使JDK都还在用1.4。技术就是生产力。摩尔定律我认为一样在软件方面是适用的,每隔18个月,软件所面临的环境就需要有一倍的生产效率的提升才能够保持软件开发的效率。用一句最近刚刚学到的例子来说,软件的技术框架,就好比盖一个楼房,你需要事先规划好地下几层的车库,你需要把层高设计好,把楼梯,电梯设计好,把采光都考虑到,框架越好,里面搭建的每个房间就越简单。

 

0

阅读 评论 收藏 禁止转载 喜欢 打印举报
已投稿到:
  • 评论加载中,请稍候...
发评论

       

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 不良信息反馈 电话:4006900000 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有