发布编辑功能的升级改造
为了实现上述目标,针对发布和编辑功能,进行了两轮升级。***轮的目标在于“平台和业务分离、业务和业务隔离”;而第二轮将更进一步,目标在于“系统之间的解耦合,提升团队协同效率”。
1.平台和业务分离,业务和业务隔离
***轮改造中,闲鱼将原先的商品发布和编辑功能从老应用中抽取到了新应用item。为了实现“平台和业务分离、业务和业务隔离”的目标,闲鱼自研了一套技术框架SWAK,具体请参考文章《业务代码解构利器--SWAK》,该文介绍了其设计思想和实现原理。接入SWAK框架后,平台逻辑和业务逻辑得到了分离,各个业务(如租房业务、免费送业务)之间的逻辑也不再耦合,而是变成package隔离(当然也是可以做成jar包隔离)。
看一看改造后的应用情况示意图:
根据这样的开发方式,我们可以把开发同学分成如下的两种角色:
如在之前的《业务代码解构利器--SWAK》一文中指出的一样,经过SWAK改造后,获得了如下的几个优点:
新接手的开发人员能够快速理解,轻松上手。
2.系统之间的解耦合,提升团队协同效率
以租房为例——租房业务的同学需要在item应用中维护一套租房发布编辑相关的逻辑(如校验地小区数据、地铁数据真实性等);租房业务的同学还需要在详情应用的逻辑中维护一套和租房详情相关的逻辑(如展示地图,展示内部设施标签);租房业务的同学还需要在交易应用的逻辑中维护一套和租房交易相关的逻辑(如预约看房)等等。租房的同学不仅仅需要着手于自己的代码逻辑,还需要修改发布和编辑应用item、还需要修改详情应用,还需要修改交易应用......这种体验是非常糟糕的,有极大的可能性接手一个简单业务就需要修改和发布四五个应用。
另一方面,从主干开发人员的角度来说,其应用不仅仅由自己或自己的小团队来维护,还有很多业务开发人员也在修改和发布此应用,且频率会远远超过主干开发任务的发布和部署频次(否则就是主干扩展点逻辑抽取得不好了)。这不利于整个应用的稳定性。A业务服务挂了,应该只影响A业务,而不应该影响主干。依此逻辑,***能做到JVM隔离。本质上来说,***轮改造完成了业务之间的解耦合,而第二轮则是系统之间的解耦合。
康威定律告诉我们:
Any organization that designs a system (defined more broadly here than just information systems) will inevitably produce a design whose structure is a copy of the organization's communication structure.
简而言之就是人员组织结构和系统结构之间的一致性。而完成系统之间的解耦合又恰恰是符合康威定律的。这一轮的改造,我们称之为“业务服务化”。
业务服务化改造方案
通过这种方式,我们将主干应用和各业务应用彻底分离了。仍然以租房业务为例,租房团队负责开发和维护租房业务的独立应用rent。租房个性化的发布和编辑需求只需要开发和部署rent应用,而不必修改主干应用。主干应用只由主干团队的同学负责维护,不会被其他业务团队的同学所开发和部署,稳定性更加能得以保障。各业务系统独立开发、独立部署。这些都大幅地减少了不必要的沟通成本、提升协同效率。
主干应用和业务应用是通过薄薄的一层接口所联系起来的,这层薄薄的接口都是“声明”:Interface定义、DO的定义和扩展点的默认Reduce策略定义。
SWAK框架的针对性改进
在之前的《业务代码解构利器--SWAK》一文中指出了,SWAK框架在应用启动的时候会通过各种注册器(registery)注册框架所需的信息。其中最重要的信息就是——业务tag及其对应的SWAK接口的实现类类名或者类实例instance。大多RPC框架都会在client端提供一个代理,代理掉内部的服务发现、保活、序列化、网络通信、反序列化等一系列操作。实际上,SWAK为了支持远程服务调用,只需要将业务tag,以及这些RPC的client的instance的对应关系注册进去就可以了。在闲鱼,RPC使用的是阿里通用的HSF框架(其类似的一个开源框架是Dubbo),这里的RPC的client就是HSF中的ConsumerBean。
上文还提到了RPC调用会引入服务超时、连接异常的概念。为何要限制超时?是因为不能被单个应用的超时占据了主干应用的服务资源而引起其他服务和整个应用系统受到影响(如大多数线程阻塞在超时调用上)。无论是超时异常还是连接异常,在业务上也有对应的处理策略。在这里,我们定义了三种异常处理策略,通过在配置上设置相应的注解,SWAK框架会自动按照策略来处理异常。这三种策略是:
减少扩展点数量
众所周知,RPC调用相对于本地调用会增加一部分的网络传输和序列化开销。对于单次调用来说,增加若干ms并没有什么问题,但对于调用10次、20次或更多,这笔开销就相当可观而应该引起重视了。为此,如何降低RPC开销,是一个必须要考虑的问题。
最可靠的方法就是降低RPC的次数。
在实践中我们发现,很多扩展点实际上都是获取业务配置。如在闲鱼业务中,“是否支持多库存”就是一种配置,如租房不支持多库存。这些业务配置项是由其业务形态所决定的,基本不会变动。因此可以将一组配置项打包一起调用,并且可以缓存下来,也可以直接由主干应用进行维护。在item应用里,这些配置项关系到主干的通用存储过程,目前由各业务方委托主干开发人员进行维护,目前配置在主干环境。可以通过阿里的动态配置平台(如Switch、Diamond)进行动态修改。
另外我们对部分邻接的扩展点进行了合并。这些相邻扩展点之间的逻辑比较简单,且不会中断主流程。通过“配置型接口”和“邻接扩展点合并”这两种操作,我们将扩展点数量降低由17个降低到了6个。要注意的是,扩展点并不是越少越好。扩展点越少,越意味着“过度拟合”,可能会对后续业务变更无法适应导致主干需要大幅改动,因此需要在数量和扩展性之间找到一个平衡。
另外值得一提的是,SWAK为配置型扩展点做了相应的小改造,并提供了查看当前配置型扩展点返回值的可视化界面。开发人员可以直观地了解当前各个业务的配置值。
接口对象定义和细节设计
在闲鱼,各种业务所需要存储的东西大同小异,从闲鱼的发布界面上来看就不难发现这一点,都是在基础对象(如标题、描述、图片)之外添加一些业务相关的数据,如拍卖业务中指定拍卖的开拍时间等信息,免费送业务中设置兑换币值,图书业务上设置条形码。即对一本图书进行拍卖当然也是允许的,这就出现了拍卖业务和图书业务叠加起来的复合型业务。
对于主干应用开发人员来说,应该提供单个接口以支持所有业务类型,这样不用每次修改或者新增业务时都需要提供新接口。从稳定性的角度考虑,这样的要求很合理。既然是单个接口,那么DO的定义也应该统一。以商品DO为例,有以下三种方式:
使用第三种的对象模型,以新加一种业务为例,其开发流程是:
业务应用在扩展点返回值中设置需要更新的数据,由主干应用合并。业务应用不应该也不可以直接修改ItemDO,避免影响其他业务的处理逻辑。对于发布和编辑这种需要持久化存储的逻辑来说,必须要强控各业务对ItemDO的修改,否则理论上来说,各业务都有可能将所有的关键字段修改得面目全非。前面提到的“配置型接口”中,就有这样的配置——该业务是否可以修改属性字段、该业务是否可以修改描述字段等配置。
总结
闲鱼的商品发布和编辑功能基于SWAK框架经过了两次改造升级,***次升级完成了平台和业务之间的解耦合以及业务和业务之间的解耦合,第二次升级通过平台和业务间使用RPC调用完成了系统和系统之间的解耦合。改造之后,能更有效地协同更多团队更快更稳定地支撑各种业务。SWAK框架依然在继续演进,如部分扩展点原则上可以通过并行处理或异步化处理来提升性能,但暂时还没有提供支持。在这两次改造中, 我们还在测试用例的采集、回放、监控告警等方面也有很多积累,敬请期待后续的文章分享。
分享文章:老代码多=过度耦合=ifelse?阿里巴巴工程师这样捋直老代码
文章源于:http://www.shufengxianlan.com/qtweb/news21/359371.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联