导读:集成开放平台采用的是混合云部署架构,包含两个大的组件,管理控制台和引擎。管理控制台是SaaS的,部署在公有云,按租户隔离。引擎部署在客户私有云。一套SaaS版的管理控制台如何适配不同客户的引擎,本文将介绍我们的最佳实践。
一、背景
集成开放平台采用的是混合云部署架构,包含两个大的组件,管理控制台和引擎。管理控制台是SaaS的,部署在公有云,按租户隔离。引擎部署在客户私有云。由于业务、管理的差异,不同的客户其本地引擎的版本也存在差异,甚至版本跨度会比较大。随着客户的增多,不同客户的版本差异越来越大,云端一套管理控制台如何兼容不同客户的后端版本,挑战也越来越大。下面通过一个例子来阐述这些问题。
二、问题
客户A的租户环境是我们19年部署的一套环境,客户B是我们另外一家客户。A客户的诉求是只需要保持稳定就可以了,不需要对他们的环境做任何的升级,B客户的诉求是我们的产品必须要不断升级去满足他们的需求。那么基于这种现状,我们给客户A在他们的服务器部署一套后端引擎,在客户B的服务器上也给他们部署了一套后端引擎。基于客户A的诉求客户A的引擎版本可能一直稳定在2.0版本,但是基于客户B的诉求,我们需要给客户B进行产品升级,那么经过一段时间的迭代客户B的后端引擎版本可能已经升级到了3.4.x.x了。但是这些客户却公用一套web端部署在公有云上。一套web端页面对应多个后端引擎造成的问题就是客户A进入web端页面之后有各种报错,因为web页面中很多的新的接口在客户A的引擎中不存在。为了解决这一个问题我们有2种方案。
三、解决方案
方案一:组件纬度加版本控制
通过在前端页面的逻辑中判断当前引擎的版本号,来决定是否要请求某一个接口、显示某一个模块,用新的数据结构还是老的数据结构:
优点:1、可以公用部分组件以及部分页面逻辑;
2、是最快速最直接的响应需求的方式;
缺点:1、因为写了很多兼容逻辑会导致项目体积过大,影响打包速度;
2、引用的三方库的升级对历史版本可能会有影响;
3、公用组件的升级需要考虑对历史版本的数据结构的兼容,增加组件的复杂度,后期可能会更加难以维护
方案二:对不同版本的前端资源进行物理隔离
我们把云端控制台分为三部分console、ipass-console、mipconsole:
console是我们云端控制台网关主要是做身份验证、租户管理等功能,租户管理模块维护了各租户的引擎地址,主要把各租户的管理控制台(mipconsole)来的请求转发到该租户所对应的服务端引擎。
ipass-console主要包含登录、租户管理等模块。从ipass-console租户管理模块的页面可以进入不同租户的管理控制台。
mipconsole是各租户管理控制台页面。包含接口中心、事件中心、服务编排、数据集成、仪表盘等功能。
ipass-console发送请求到console控制台网关,网关会直接操作console控制台的数据库,由于各租户的服务端引擎是私有化部署部署在客户自己的服务器上,所以不同租户的引擎地址不一样,mipconsole发送请求到console控制台网关,网关会把该请求转发到租户的服务端引擎,引擎接收到请求会操作引擎端数据库。由于ipass-console不需要跟后端引擎做关联的所以不需要做版本区分。但是mipconsole是各租户的管理控制台的功能。那么mipconsole是如何做到对各个租户的管理控制台的web端资源做到物理隔离的呢?答案是通过git的分支来做到对不同租户的web端资源来进行物理隔离。
下面我们结合上面我们的问题来进行阐述:
1、web端各版本资源的物理隔离:
我们如何通过git分支来做不同的租户之间web端资源的完全隔离呢?首先我们把客户A的租户的前端资源当作一个基线分支,基于这个基线分支切出一个开发分支,在这个开发分支上开发客户B的新需求,当第一批的需求开发完成并且测试验收通过之后,我们会基于这个开发分支打一个tag,并且把开发分支合回基线分支,在基线分支编译出一个正式静态资源包放在我们主工程ipass-console的web目录下。下次在有新的需求时在基于最新的基线分支切出开发分支,重复上述过程。
如果后期在迭代过程中发现之前某一个版本有bug,那么我们会基于那个版本的最新的tag切出一个hotfix分支修复该bug,修复完成并测试通过之后基于当前的hotfix分支生成一个新的tag,同时基于当前的分支编译生成一个新的静态资源包替换之前老的资源包。bug的修改不会新增静态资源包,只有无法兼容的新需求(需要写版本判断的这种)才会新增一个静态资源包。这就是mipconsole各个租户管理控制台的前端资源的物理隔离方案。
2、web端各版本资源的加载、解析:
console是我们云端控制台网关,因为不同的租户引擎地址不一样,所以前端无法直接访问引擎地址,所以前端会先发请求云端控制台网关 ,网关在把请求转发到相应租户的引擎服务去。在项目初始化的时候console会去遍历主工程(ipass-console)下的web目录下资源目录的文件夹名称生成一个前端静态资源目录与后端引擎版本号的一个映射文件,缓存在内存中。当console接收到前端的请求地址是以/cloud/ 开头的就会根据请求的参数租户corp_id和环境env_id去数据库里查询当前环境所对应的引擎版本号,然后通过引擎的版本号去映射文件里面匹配到前端的静态资源的文件夹名称,把匹配到的静态资源文件下的index.html返回给浏览器,浏览器下载了index.html后js会自动解析并导航到对应页面。这样进入某一个的租户的管理控制台之后浏览器只会加载某一个版本的前端静态资源。
以下是我们的项目工程目录:
1、 资源工程的各个版本的分支,如下图:
2、主工程、各个版本静态资源包以及各个静态资源包所对应的后端引擎版本号,如下图:
V3.1.0.0 、V3.2.0.0代表的是前端资源的版本号,minVersion 代表后端引擎的最小版本号。如果当前后端引擎的版本号3.1.1.1 大于等于3.1.0.0小于3.1.22.0则对应加载3.1.0.0版本的前端资源。前端版本资源与后端版本资源是一对多的关系,以实际的正式发版时的后端版本号做为前端匹配的最小版本号。
3、各个版本资源包所对应的tag号,如下图:
四、总结
针对多租户的前端工程管理的方案困扰了我们很久,市面上也没有我们这种业务场景所以我们也没有可以参考的标准解决方案,我们一直在思考寻找最适合我们的解决方案,在这期间我们发现现在比较流行的微前端的思想或许可以解决我们的问题,但是当我们去预研这些流行的微前端框架single-spa、qiankun等发现都不太适合我们的业务场景,于是我们基于这些思想预研出了最适合我们自己业务场景的方案。在我们的工作中对于一些比较好技术和框架我们不能生搬硬套,而是要基于我们实际的业务场景来考虑是否适合我们,我们可以借鉴别人好的思想来形成我们自己的技术方案和技术体系。
------ END ------
作者简介
郭同学: 前端工程师,目前负责集成开放平台的研发工作。
也许您还想看:
技术分享|Java SDK动态数据源和上下文机制
技术分享|NodeJS分布式链路追踪实现
技术分享 | Java SDK 元数据驱动的事件通信架构
技术分享|Hangfire深度实践
技术分享 | APT结合JavaPoet生成模板化Java源代码文件
技术分享 | 玩转高效UI自动化测试
更多明源云·天际开放平台场景案例与开发小知识,可以关注明源云天际开发者社区公众号:
【建模】文档服务提供高保真打印模式
明源云·天际硬核技术认可:获华为鲲鹏技术认证书
天际·开发者社区“重装发布”!