SaaS软件架构设计系列 | 6-2 私有化部署

336 阅读7分钟

私有化部署

私有化部署面临的挑战

在国内的SaaS软件市场,发展到一定阶段,都可能会遇到大客户私有化部署的需求。如果SaaS系统设计之初没有考虑私有化部署场景,会就面临诸多挑战。我们试着列举一些可能存在的典型问题:

  • 资源需求过多:SaaS软件发展到一定阶段,都会有大量的用户访问,而且较强的伸缩能力,一般都是分布式的架构或微服务架构。一般需要私有化部署的虽然是大客户,但一个租户的体量相比于SaaS的规模还是分小很多倍,所以基于现有架构的资源需求就显得太多。特别是当客户的IT人员没有接触过微服务+容器化部署时,对资源的需求也很不理解。例如每个服务对应一个数据库,客户理解只需要一个应用一个库。甚至整个系统只需要一个业务库,一个日志库,都在关系型数据库中,为什么日志还需要单独的存储中间件?再比如系统需要很多的域名,客户的预期只需要一个域名,等等。
  • 安全要求更多:SaaS软件一般都是开放到互联网中使用,而本地部署的软件,很多要求只能内网访问,所以安全和网络的限制更严格。比如SaaS可能会用到云厂商的PaaS服务,本地化部署需要对访问的IP添加白名单,但云厂商PaaS服务很多无法提供稳定的IP清单。有的客户要求运行的日志(非业务审计日志)不能出网,排查问题得申请VPN连到内网查看,效率低下。
  • 不开放外网:SaaS软件基于敏捷开发的方式进行动作,CI/CD过程有大量的自动化处理,由于客户不开放外网,所以无法使用CI/CD工具,手工部署面临成千上万的配置,会直接让人崩溃。
  • 不允许使用或必须使用指定的中间件:一方面由于国产化的需求,导致开源中间件不允许使用;另一方面客户有自己的云平台,有类似能力的中间件,由有技术栈统一的要求。为了满足这类客户的要求,需要付出巨大的代价。例如有个客户云平台有Apollo,要求配置中心只能使用Apollo,对于使用Nacos开发的产品来说,真是欲哭无泪。
  • 必须使用某种语言或不允许使用某些技术:客户更多是基于“自主可控”的需求来提出要求,想着有一天你由于各种原因不和他玩了,他能够继续维护和扩展系统。比如必须使用Java语言,不能使用容器化部署等。
  • 数据迁移成本高:如果在设计时,没有严格的按租户区分数据,在数据迁移时可能需要单独的工具进行迁移和验证。例如非结构化数据没有很好的按租户区分(参考之前的存储设计建议),某些通用域的服务没有按租户区分业务数据,例如短信、电子合同等。还有一些在数据库使用完整路径的URL,例如图片地址之类的,迁移后需要修改域名(在设计上就应该使用相对路径),如果分享后的链接没有使用短链接服务转换,甚至无法完成迁移。

以上只是一些典型的例子,实际过程中还会碰到五花八门的各种要求。究期原因主要有两个方面:

  1. SaaS系统面临的问题域和私有化部署场景要解决的问题域有天然的冲突,一个更开放,一个更收敛。加上设计之初没有考虑私有化部署的场景,导致很多设计在私有化部署时成为障碍;
  2. 部分要求私有化部署的客户,并没有把SaaS当一个软件产品看待,而是在用项目外包的方式提出自己的要求。

面向私有化部署的设计建议

以下是对于存在私有化部署可能时的设计建议,某些建议实施成本可能会比较高,或对团队的效率和技术发展产生限制,这些需要根据私有化用户的规模,可能生产的收益来整体考虑。

  • 抽象环境相关配置项:私有化部署时,不同环境的初始化主要是环境相关的配置差异,因此有必要将所有服务环境相关的配置抽象变量进行统一管理。环境相关的配置主要包括资源、中间件、域名、密钥和运行参数等信息。运行参数可以根据部署规模的不同,做成模板,根据特殊情况再进行微调。
  • 管理好服务间的强/弱依赖:在私有化部署时,客户可能并未购买所有的产品,因此只需要部署部分产品。在SaaS系统中,很多产品默认是一定存在的,所以设计时都是“强依赖”,也就是被依赖服务不存在时,系统运行会出现异常。面对私有化部署的场景,在产品设计之初就需要考虑将非必须的服务设计成“弱依赖”,也就是被依赖服务不存在时,对应的功能关闭或对应的信息不显示,但系统能够正常运行。强弱的依赖的信息管理也需要有设计支撑,最好能够做到基础的架构中(配置不正确系统无法运行),否则需要单独人工管理,容易出现错漏。
  • 数据库升级支持版本化:私有化部署后,客户可能会提出变更管理的需求,私有化环境无法跟随SaaS环境的发布。因此可能存在按周期(月/季等)更新私有化环境的场景。更新时可能SaaS已经更新了多个版本。对于应用和配置来说,只需要给最终态或使用某个版本就可以,但对于数据库升级,则需要合并多个版本的更新。因此需要对数据库升级进行版本化管理(数据升级可能是执行SQL,也可能是运行一个任务,都需要进行版本化管理),并区分发布的SQL和数据处理的SQL。
  • 谨慎添加新域名和中间件类型:基于挑战中的场景描述,域名和依赖的中间件类型越少越好,或者能够做到SaaS只使用多域名或不同类型中间件,私有化部署时能够收敛。
  • 谨慎引入新技术栈和框架:一方面考虑挑战中的场景描述,另一方面私有化部署想要高效需要很多的工具和自动化建设,新的技术栈需要完成工具链的适配和同步进化成本较高。
  • 服务支持可分可合部署:服务多,需要资源多,使用容器化部署,都可能成为私有化部署的障碍。如果架构上支持服务的合并部署,支持本地化部署,则可以较好的满足此类客户的要求,但成本也相对较高。
  • 避免云绑定:SaaS开发起初都是在云厂商提供的IaaS和PaaS部署,有些服务或功能可能只是云厂商特有的,无法使用开源产品替代,导致无法进行私有化部署。因此需要避免使用云厂商独有的无法被替代的服务和功能。
  • 显示的区分租户的数据:不管是结构化数据还是非结构化数据,应该能够很方面的对数据的所属租户进行区分和识别,以便于数据迁移工作的进行和检验,并能够自动化。
  • 依赖短链接服务分享链接:私有化部署后,往往需要修改域名。如果直接使用功能对应的域名,私有化后将很难进行转发处理。通过使用短链接服务,针对已私有化租户分享的链接,可以方便的统一进行正确的转发。