摘要:今天介绍下我一年前完成的一个两个独立系统的模块打通过程,换句话说就是系统可以直接使用系统的业务模块。需求分析上面是这两个系统的基本架构,拆分成线上线下两个部分。问题二这个模块在系统中调用时,如何找对路径。
面试时经常问的一个问题是,你最近或者做过的项目中挑战最大的内容,然后顺着其中的技术点挖一些更深入的内容,看看候选人了解多少,理解程度。
然后突然想了想我做的有什么难度比较大的项目,可以给大家分享下。
今天介绍下我一年前完成的一个两个独立系统的模块打通过程,换句话说就是A系统可以直接使用B系统的业务模块。
背景介绍A系统是一个古老的系统,B系统是一个新做的系统,(原本是希望A系统的功能全部迁移到B系统上的,但是由于各种原因搁置了)当时结果导致两个系统在同时使用和升级。
随着业务的开发,很多需求在A和B系统之间产生了关联性,例如B系统上线了一个新产品,然后为了增加入口和使用量,需要在A系统上可以直接调用新产品的某个功能。
直观的解决方案是A系统上面复制粘贴一份B系统上面这个产品的功能,但是问题就来了,未来维护起来怎么办,同时维护两份代码?以后这样的需求多了怎么办,重复代码越来越多?
另外一个解决办法就是A,B两个系统间的融合。当然这样评估的一个前提是A和B虽然是两个系统,但是大家开发模式,底层依赖还是相似的。
需求分析上面是这两个系统的基本架构,拆分成线上线下两个部分。
A网站有两个业务模块A1和A2。
B网站有三个业务模块,B1,B2,B3。
现在的需求是B1这个模块不仅能在B系统中运行,而且可以共享到A系统中。
目标如下图:
那么问题来了:
问题一支持业务代码的底层dep和common不一样。
随着时间的推移,dep依赖第一个是引入的库有些差别,第二个更加严重是是大部分库的版本已经不一样了。
业务模块的底层就像是生态环境,如果生态环境差别越大,那么这两个生态融合在一起的困难也就越大。
问题二B1这个模块在A系统中调用时,如何找对路径。
举个例子:
B系统中有一个 module/b/c/d.js;
B1中require了一个 module/b/c/d,在B系统中是可以正确访问到的。
但是如果在A系统中调用到B1的require的module/b/c/d。它是会找到A系统中的module/b/c/d.js;
这只是其中的一个例子,由于系统中的AMD模式,路径的寻找也是一个坑点。
当然对于上面的问题可以通过map方式(esl.js中有个map,require.js应该也有对应的)。当时是用过另外一种方式解决的。
问题三编译两个问题,
一是路径问题,当时坑我最深的。
二是业务模块独立打包,A系统中应该是仅仅需要B1这个业务,而不是所有B系统中的代码。
如何对开发人员透明,这个很关键。如果系统融合了,一线的开发人员需要为此做很多事情,就比较失败了。
所以整个调用过程如何让开发无感知,B系统中正常开发一个模块,A系统通过一个api就能直接使用了,也不需要区分线上线下。
具体步骤主要问题抛出了,后面就是看如何一一对应的解决问题了。
当然了上面介绍的以外,还有很多细节问题,例如融合后样式冲突这种很多细节上面的坑。只是这些没有上面四个问题那么严重。
第一步,底层打平dep打平(1)A系统中补充B系统中新增的库,相对简单
dep打平(2)A和B系统中有差异的库,都升级到同样版本,这个非常坑,由于很多使用的是公司或者部门内部的库,升级不想外部jquery一样对开发透明,他们的升级绝对不是透明的,哪怕是百度最火的echart。所以解决升级库的兼容问题是一个工作量很大的活。
common基础依赖合并。找出不同内容互补,然后相同又冲突的内容,修改打补丁方式,虽然有坑,但是经理了dep的升级,觉得还ok。
完成上面三步后的一个期望的成果是,B1模块以及依赖的内容可以直接复制到A系统中,在A里面可以直接调用打开。
注意一些细节就是初始化是否相同,A和B如果初始化不一样,可能在A系统调用B1时,B1有些内容缺少初始化过程。(这种就是属于细节上的坑了)
第二部,处理path路径当时处理思路比较简单,B1模块前面统一加上B1这个前缀,这样就能够在require时找到指定的路径了。
这个地方的难点在于打包编译,因为破坏了默认的打包规则,而且根据一些打包的扩展配置也无法达到期望。
当时解决的方式是仔细的研究了打包编译流程,很大程度上面重写了或者说hack了默认的打包规则。
其实打包编译都研究到这里了,也就顺便把问题三解决了。当时的对于打包的研究已经可以安装需要随意打包了。
这里的预期效果就是B1模块在B自己的系统中,A中可以调用打开了
第三部,对开发人员透明完成上面步骤后,有一个遗留问题是,线上打开的方式和线下打开的方式不一样,对于开发人员非常不友好。
所以这一步应该是优化过程,让这个功能更加完善,所以写了一个简单的api,开发人员只需要调用api即可,不需要考虑线上和线下逻辑。这个复杂的逻辑包含到了api中处理。
项目难点我个人认为这个项目的难点:
对于两个系统的架构要非常熟悉
对于打包编译需要非常熟悉,因为一旦涉及到线上和线下,编译就是必须要了解的内容
对于系统底层代码要熟悉,因为在升级dep过程中,很多版本兼容bug必须要定位到底层代码中
对于AMD需要熟悉,当时定位甚至发现了esl.js和require.js在某种场景的细微区别
目前状态在最近一年中,A和B两个系统以及融合在一起了。
个人博客http://tangguangyao.github.io/
微信公众号文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/78858.html
摘要:模块内聚和耦合的基础知识是软件评测师考试的重要考点,经常出现在上午场的客观选择题当中。外部耦合模块间通过软件之外的环境联结如将模块耦合到特定的设备格式通信协议上时称为外部耦合。这种模块之间的耦合称之为内容耦合。 模块内聚和耦合的基础知识是软件评测师考试的重要考点,经常出现在上午场的客观选择题当中。模块独立是指模块只完成系统...
摘要:是一个相对比较新的微服务框架,年才推出的版本虽然时间最短但是相比等框架提供的全套的分布式系统解决方案。提供线程池不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务器雪崩的问题。通过互相注册的方式来进行消息同步和保证高可用。 Spring Cloud 是一个相对比较新的微服务框架,...
摘要:解释模块耦合性的含义,对不同的耦合举例说明耦合性,也叫耦合度,是对模块间关联程度的度量。模块间的耦合度是指模块之间的依赖关系,包括控制关系调用关系数据传递关系。软件设计中通常用耦合度和内聚度作为衡量模块独立程度的标准。 ...
摘要:子模块的创建和设置在创建好的父模块中右键填写项目名称选择项目中需要的部件完成父模块的创建。对于多个模块共同的依赖,在父中设置即可。 本文旨在用最通俗的语言讲述最枯燥的基本知识 最近要对一个不大不小的项目进行重构,用spring觉得太过于繁琐,用cloud又有觉得过于庞大,维护的人手不够;权衡之下,最终选了springboot作为架子,但是因为项目涉及的业务模块较多,各个模块之间的业务交...
阅读 2015·2021-11-11 16:54
阅读 2088·2019-08-30 15:55
阅读 3589·2019-08-30 15:54
阅读 372·2019-08-30 15:44
阅读 2209·2019-08-30 10:58
阅读 407·2019-08-26 10:30
阅读 3032·2019-08-23 14:46
阅读 3167·2019-08-23 13:46