随着业务的不断发展,软件系统不可避免地趋于熵增:复杂度越来越高,研发效率越来越差,稳定性逐渐下降。这时候,抽象出核心能力,走向平台化,就成了很多系统的首要选择。笔者根据自己的经验,总结了几个搭建平台的思路,希望对大家搭建平台有所帮助。平台化有以下优势:复用性强:核心逻辑复用,业务功能只构建在平台之上的业务层,降低构建成本;研发效率高:平台服务作为通用的能力基础设施,业务只需要关注需求,不用关心在平台底层实现复杂的能力;降低复杂性:平台职责边界和模块划分合理,对外开发的接口也直观简洁;稳定性:平台服务的稳定性是重中之重,一般都有专门的团队维护,稳定性强于一般业务系统;平台搭建的几种方式1、嵌入式平台提供类容器的功能,业务端以Jar包的形式嵌入到平台中,类似于传统的tomcat部署多个war包。该实现方法平台提供通用的能力接口和业务扩展点,业务方实现业务扩展点实现业务逻辑。一般有统一的入口(比如tomcat提供的域名+端口),根据租户ID(比如tomcat的serverPath)来区分业务方,平台的底层存储和模型也有tenantID标识符。优势:运维:平台统一运维,减少业务方的工作量;对外接口:统一的对外接口,减少调用方的工作量;缺点:业务方功能受限:一般无法做重量级任务,平台是基于扩展点的方法提供给业务方进行扩展,其他能力应该受到限制;jar包冲突和类冲突:平台自身依赖较多,业务端jar包依赖也较多。如果发生冲突,整个平台将不可用,下面将介绍几种避免方法;业务隔离性差:不同的业务方可能会相互影响;业务隔离的常用解决方案:每个业务方提供一个集群;使用类加载器隔离jar包,但仍然可能无法解决jar包冲突的问题;业务方提供fatjar,更改所有依赖包的包路径,如MavenShadePlugin插件;2.接口依赖平台也可以通过远程依赖来集成业务功能。这样可以避免jar包冲突、业务功能受限等问题。这个解决方案也会有一些限制。比如原来的jar包依赖本地调用,现在都是远程调用,对性能和事务保障提出了新的挑战;需要保证接口兼容性;平台与业务的交互,从原来的对象交互到RPC接口,从设计到编解码等;该方案适用于平台与业务层交互较少,扩展点相对固定的场景,比如API渲染服务,平台提供渲染模板接口,业务方实现接口填写字段。优点:隔离:平台和业务完全隔离;业务方方便集成其他业务:平台扩展点只是业务方的一种能力,可以在现有服务上提供;缺点:接口变更复杂:如果要变更接口,所有业务方都需要迭代;交互复杂:都是通过RPC进行交互,需要将一些扩展字段编解码成String传输;平台端:如果业务端的服务端出现异常,需要平台端提供限流、降级、自下而上的能力;3、中型和桌面型。以上两种模式都是基于平台的。对于上层来说,都是感知平台。它们适用于交互界面相对固定的场景,但不太适合交互差异较大的业务。中台的思路是提供通用的业务能力,业务方可以基于中台能力快速开发自己的业务,独立提供服务或页面。平台与平台的区别:角度不同:平台侧重于去重和集成;为其他产品提供更好的服务;优点:能力专注??:只需要提供核心能力支持,不关心与用户的交互;更易复用:平台不依赖于业务的扩展点,只是业务方对平台的单向依赖;缺点:个性化能力弱:因为没有扩展点,只提供通用能力;平台建设的常见模式1.DSL领域特定语言DSL(DomainSpecificLanguage)是一种针对某一领域的有限表达的计算机程序设计语言。DSL富有表现力,通常用于关注特定领域或问题。在平台建设中,一般使用DSL来屏蔽平台复杂的业务逻辑,将简单的能力接口以DSL的形式暴露给业务方。比如非常有名的Gradle就是一个DSL表达式,比Maven具有更灵活的特性。关于如何构建DSL,请参考作者的博客:使用Groovy构建DSL2,Specification模式Specification模式用于解决与“业务规则”相关的复杂性。什么是商业规则?比如在电商业务场景中,需要判断:账户的有效状态,是否是VIP,活动价格的有效期,账户余额。在常规的代码开发中,有3种处理方式:在业务流程代码中逐例编写;缺点是会导致可重用性和可维护性较差;新建静态类,如OrderValidator、TimeValidator等,缺点是不足以处理组合逻辑(与,或);在模型类中进行checking时,缺点是类中会混入越来越多的非领域逻辑,过多的逻辑会掩盖业务的核心业务规则;规范模式认为验证逻辑都是“动作”,需要单独建模,模型都是值对象。接口的一般模式如下:publicinterfaceSpecification
